diff --git a/docs/libcurl/opts/CURLINFO_RETRY_AFTER.md b/docs/libcurl/opts/CURLINFO_RETRY_AFTER.md
index 0dca2e509d..87700bc331 100644
--- a/docs/libcurl/opts/CURLINFO_RETRY_AFTER.md
+++ b/docs/libcurl/opts/CURLINFO_RETRY_AFTER.md
@@ -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.
diff --git a/lib/http.c b/lib/http.c
index 18eba54d89..e155200a52 100644
--- a/lib/http.c
+++ b/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;
diff --git a/tests/data/test1596 b/tests/data/test1596
index f05f0ec146..8b94cd12fa 100644
--- a/tests/data/test1596
+++ b/tests/data/test1596
@@ -13,9 +13,9 @@ If-Modified-Since
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
@@ -42,8 +42,9 @@ Host: %HOSTIP:%HTTPPORT
Accept: */*
+# Retry-After time is limited to 6 hours (21600 seconds)
-Retry-After 172066
+Retry-After 21600
diff --git a/tests/libtest/lib1594.c b/tests/libtest/lib1594.c
index bf25ffbeb5..2a31a720e4 100644
--- a/tests/libtest/lib1594.c
+++ b/tests/libtest/lib1594.c
@@ -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: