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 -
|
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.
|
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
|
# DEFAULT
|
||||||
|
|
||||||
Zero if there was no header.
|
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);
|
(void)curlx_strtoofft(v, NULL, 10, &retry_after);
|
||||||
if(!retry_after) {
|
if(!retry_after) {
|
||||||
time_t date = Curl_getdate_capped(v);
|
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 */
|
/* 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;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -13,9 +13,9 @@ If-Modified-Since
|
|||||||
<reply>
|
<reply>
|
||||||
<data nocheck="yes">
|
<data nocheck="yes">
|
||||||
HTTP/1.1 429 Too Many Requests
|
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
|
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>
|
</data>
|
||||||
</reply>
|
</reply>
|
||||||
@ -42,8 +42,9 @@ Host: %HOSTIP:%HTTPPORT
|
|||||||
Accept: */*
|
Accept: */*
|
||||||
|
|
||||||
</protocol>
|
</protocol>
|
||||||
|
# Retry-After time is limited to 6 hours (21600 seconds)
|
||||||
<stdout>
|
<stdout>
|
||||||
Retry-After 172066
|
Retry-After 21600
|
||||||
</stdout>
|
</stdout>
|
||||||
</verify>
|
</verify>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|||||||
@ -49,12 +49,6 @@ CURLcode test(char *URL)
|
|||||||
if(res)
|
if(res)
|
||||||
goto test_cleanup;
|
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);
|
printf("Retry-After %" CURL_FORMAT_CURL_OFF_T "\n", retry);
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user