]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: ignore invalid Retry-After times
authorJay Satiro <raysatiro@yahoo.com>
Thu, 26 Dec 2024 20:38:39 +0000 (15:38 -0500)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 31 Dec 2024 08:19:22 +0000 (03:19 -0500)
- 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

docs/libcurl/opts/CURLINFO_RETRY_AFTER.md
lib/http.c
tests/data/test1596
tests/libtest/lib1594.c

index 0dca2e509d1538fba96128af9fe734e5a3407611..87700bc331c385459cf0cb323f430793ffa0a427 100644 (file)
@@ -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.
index 18eba54d899c785ba128dda6f2a48b682fb533b4..e155200a52091b6ad499d35b28685b0d854bc202 100644 (file)
@@ -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;
index f05f0ec146a48023efa541d88dcfb8a855a088bb..8b94cd12fa09f1c4f2c7211af61499e29163cb97 100644 (file)
@@ -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: */*\r
 \r
 </protocol>
+# Retry-After time is limited to 6 hours (21600 seconds)
 <stdout>
-Retry-After 172066
+Retry-After 21600
 </stdout>
 </verify>
 </testcase>
index bf25ffbeb50a4309034514a4a9656c773d2a0b53..2a31a720e4543530779a94c6149acb6a4df60018 100644 (file)
@@ -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: