http: ignore invalid Retry-After times
- Treat negative Retry-After date-based times as 0. - Treat Retry-After times greater than 6 hours as 6 hours. Prior to this change Retry-After did not have a limited range and the server could have set a time greater than 6 hours or a date in the past that would result in a negative time, either of which may be unexpected by the user. The 6 hour limit is purposely not documented so that it can be changed in the future if necessary. Closes https://github.com/curl/curl/pull/15833
This commit is contained in:
parent
8d1f26b866
commit
6c70ec16c7
@ -36,6 +36,11 @@ While the HTTP header might contain a fixed date string, the
|
||||
CURLINFO_RETRY_AFTER(3) always returns the number of seconds to wait -
|
||||
or zero if there was no header or the header could not be parsed.
|
||||
|
||||
This option used to return a negative wait time if the server provided a date
|
||||
in the past. Since 8.12.0, a negative wait time is returned as zero. In any
|
||||
case we recommend checking that the wait time is within an acceptable range for
|
||||
your circumstance.
|
||||
|
||||
# DEFAULT
|
||||
|
||||
Zero if there was no header.
|
||||
|
||||
14
lib/http.c
14
lib/http.c
@ -2901,11 +2901,19 @@ static CURLcode http_header(struct Curl_easy *data,
|
||||
(void)curlx_strtoofft(v, NULL, 10, &retry_after);
|
||||
if(!retry_after) {
|
||||
time_t date = Curl_getdate_capped(v);
|
||||
if((time_t)-1 != date)
|
||||
time_t current = time(NULL);
|
||||
if((time_t)-1 != date && date > current) {
|
||||
/* convert date to number of seconds into the future */
|
||||
retry_after = date - time(NULL);
|
||||
retry_after = date - current;
|
||||
}
|
||||
}
|
||||
data->info.retry_after = retry_after; /* store it */
|
||||
if(retry_after < 0)
|
||||
retry_after = 0;
|
||||
/* limit to 6 hours max. this is not documented so that it can be changed
|
||||
in the future if necessary. */
|
||||
if(retry_after > 21600)
|
||||
retry_after = 21600;
|
||||
data->info.retry_after = retry_after;
|
||||
return CURLE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -13,9 +13,9 @@ If-Modified-Since
|
||||
<reply>
|
||||
<data nocheck="yes">
|
||||
HTTP/1.1 429 Too Many Requests
|
||||
Date: Thu, 11 Jul 2019 02:26:59 GMT
|
||||
Date: Wed, 31 Dec 2036 02:26:59 GMT
|
||||
Server: test-server/swsclose
|
||||
Retry-After: Thu, 11 Jul 2024 02:26:59 GMT
|
||||
Retry-After: Wed, 31 Dec 2036 02:26:59 GMT
|
||||
|
||||
</data>
|
||||
</reply>
|
||||
@ -42,8 +42,9 @@ Host: %HOSTIP:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
# Retry-After time is limited to 6 hours (21600 seconds)
|
||||
<stdout>
|
||||
Retry-After 172066
|
||||
Retry-After 21600
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -49,12 +49,6 @@ CURLcode test(char *URL)
|
||||
if(res)
|
||||
goto test_cleanup;
|
||||
|
||||
#ifdef LIB1596
|
||||
/* we get a relative number of seconds, so add the number of seconds
|
||||
we're at to make it a somewhat stable number. Then remove accuracy. */
|
||||
retry += time(NULL);
|
||||
retry /= 10000;
|
||||
#endif
|
||||
printf("Retry-After %" CURL_FORMAT_CURL_OFF_T "\n", retry);
|
||||
|
||||
test_cleanup:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user