mirror of
https://github.com/moparisthebest/curl
synced 2024-12-24 00:58:48 -05:00
CURLINFO_RETRY_AFTER: parse the Retry-After header value
This is only the libcurl part that provides the information. There's no user of the parsed value. This change includes three new tests for the parser. Ref: #3794
This commit is contained in:
parent
2bdb26a507
commit
f933449d3b
@ -157,6 +157,9 @@ Upload size. See \fICURLINFO_CONTENT_LENGTH_UPLOAD_T(3)\fP
|
|||||||
.IP CURLINFO_CONTENT_TYPE
|
.IP CURLINFO_CONTENT_TYPE
|
||||||
Content type from the Content-Type header.
|
Content type from the Content-Type header.
|
||||||
See \fICURLINFO_CONTENT_TYPE(3)\fP
|
See \fICURLINFO_CONTENT_TYPE(3)\fP
|
||||||
|
.IP CURLINFO_RETRY_AFTER
|
||||||
|
The value from the from the Retry-After header.
|
||||||
|
See \fICURLINFO_RETRY_AFTER(3)\fP
|
||||||
.IP CURLINFO_PRIVATE
|
.IP CURLINFO_PRIVATE
|
||||||
User's private data pointer.
|
User's private data pointer.
|
||||||
See \fICURLINFO_PRIVATE(3)\fP
|
See \fICURLINFO_PRIVATE(3)\fP
|
||||||
|
63
docs/libcurl/opts/CURLINFO_RETRY_AFTER.3
Normal file
63
docs/libcurl/opts/CURLINFO_RETRY_AFTER.3
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH CURLINFO_RETRY_AFTER 3 "6 Aug 2019" "libcurl 7.66.0" "curl_easy_getinfo options"
|
||||||
|
.SH NAME
|
||||||
|
CURLINFO_RETRY_AFTER \- returns the Retry-After retry delay
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_RETRY_AFTER, curl_off_t *retry);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Pass a pointer to a curl_off_t variable to receive the number of seconds the
|
||||||
|
HTTP server suggesets the client should wait until the next request is
|
||||||
|
issued. The information from the "Retry-After:" header.
|
||||||
|
|
||||||
|
While the HTTP header might contain a fixed date string, the
|
||||||
|
\fICURLINFO_RETRY_AFTER(3)\fP will alwaus return number of seconds to wait -
|
||||||
|
or zero if there was no header or the header couldn't be parsed.
|
||||||
|
.SH DEFAULT
|
||||||
|
Returns zero delay if there was no header.
|
||||||
|
.SH PROTOCOLS
|
||||||
|
HTTP(S)
|
||||||
|
.SH EXAMPLE
|
||||||
|
.nf
|
||||||
|
CURL *curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
CURLcode res;
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
if(res == CURLE_OK) {
|
||||||
|
curl_off_t wait = 0;
|
||||||
|
curl_easy_getinfo(curl, CURLINFO_RETRY_AFTER, &wait);
|
||||||
|
if(wait)
|
||||||
|
printf("Wait for %" CURL_FORMAT_CURL_OFF_T " seconds\\n", wait);
|
||||||
|
}
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
.fi
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in curl 7.66.0
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR CURLOPT_STDERR "(3), " CURLOPT_HEADERFUNCTION "(3), "
|
@ -43,6 +43,7 @@ man_MANS = \
|
|||||||
CURLINFO_REDIRECT_URL.3 \
|
CURLINFO_REDIRECT_URL.3 \
|
||||||
CURLINFO_REQUEST_SIZE.3 \
|
CURLINFO_REQUEST_SIZE.3 \
|
||||||
CURLINFO_RESPONSE_CODE.3 \
|
CURLINFO_RESPONSE_CODE.3 \
|
||||||
|
CURLINFO_RETRY_AFTER.3 \
|
||||||
CURLINFO_RTSP_CLIENT_CSEQ.3 \
|
CURLINFO_RTSP_CLIENT_CSEQ.3 \
|
||||||
CURLINFO_RTSP_CSEQ_RECV.3 \
|
CURLINFO_RTSP_CSEQ_RECV.3 \
|
||||||
CURLINFO_RTSP_SERVER_CSEQ.3 \
|
CURLINFO_RTSP_SERVER_CSEQ.3 \
|
||||||
|
@ -267,6 +267,7 @@ CURLINFO_REDIRECT_TIME_T 7.61.0
|
|||||||
CURLINFO_REDIRECT_URL 7.18.2
|
CURLINFO_REDIRECT_URL 7.18.2
|
||||||
CURLINFO_REQUEST_SIZE 7.4.1
|
CURLINFO_REQUEST_SIZE 7.4.1
|
||||||
CURLINFO_RESPONSE_CODE 7.10.8
|
CURLINFO_RESPONSE_CODE 7.10.8
|
||||||
|
CURLINFO_RETRY_AFTER 7.66.0
|
||||||
CURLINFO_RTSP_CLIENT_CSEQ 7.20.0
|
CURLINFO_RTSP_CLIENT_CSEQ 7.20.0
|
||||||
CURLINFO_RTSP_CSEQ_RECV 7.20.0
|
CURLINFO_RTSP_CSEQ_RECV 7.20.0
|
||||||
CURLINFO_RTSP_SERVER_CSEQ 7.20.0
|
CURLINFO_RTSP_SERVER_CSEQ 7.20.0
|
||||||
|
@ -2623,8 +2623,9 @@ typedef enum {
|
|||||||
CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
|
CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
|
||||||
CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
|
CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
|
||||||
CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
|
CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
|
||||||
|
CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57,
|
||||||
|
|
||||||
CURLINFO_LASTONE = 56
|
CURLINFO_LASTONE = 57
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
|
@ -246,7 +246,6 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
|||||||
case CURLINFO_PROTOCOL:
|
case CURLINFO_PROTOCOL:
|
||||||
*param_longp = data->info.conn_protocol;
|
*param_longp = data->info.conn_protocol;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CURLE_UNKNOWN_OPTION;
|
return CURLE_UNKNOWN_OPTION;
|
||||||
}
|
}
|
||||||
@ -304,7 +303,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
|||||||
case CURLINFO_REDIRECT_TIME_T:
|
case CURLINFO_REDIRECT_TIME_T:
|
||||||
*param_offt = data->progress.t_redirect;
|
*param_offt = data->progress.t_redirect;
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_RETRY_AFTER:
|
||||||
|
*param_offt = data->info.retry_after;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_UNKNOWN_OPTION;
|
return CURLE_UNKNOWN_OPTION;
|
||||||
}
|
}
|
||||||
|
13
lib/http.c
13
lib/http.c
@ -3953,6 +3953,19 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else if(checkprefix("Retry-After:", k->p)) {
|
||||||
|
/* Retry-After = HTTP-date / delay-seconds */
|
||||||
|
curl_off_t retry_after = 0; /* zero for unknown or "now" */
|
||||||
|
time_t date = curl_getdate(&k->p[12], NULL);
|
||||||
|
if(-1 == date) {
|
||||||
|
/* not a date, try it as a decimal number */
|
||||||
|
(void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* convert date to number of seconds into the future */
|
||||||
|
retry_after = date - time(NULL);
|
||||||
|
data->info.retry_after = retry_after; /* store it */
|
||||||
|
}
|
||||||
else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) {
|
else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) {
|
||||||
/* Content-Range: bytes [num]-
|
/* Content-Range: bytes [num]-
|
||||||
Content-Range: bytes: [num]-
|
Content-Range: bytes: [num]-
|
||||||
|
@ -1071,6 +1071,7 @@ struct PureInfo {
|
|||||||
long numconnects; /* how many new connection did libcurl created */
|
long numconnects; /* how many new connection did libcurl created */
|
||||||
char *contenttype; /* the content type of the object */
|
char *contenttype; /* the content type of the object */
|
||||||
char *wouldredirect; /* URL this would've been redirected to if asked to */
|
char *wouldredirect; /* URL this would've been redirected to if asked to */
|
||||||
|
curl_off_t retry_after; /* info from Retry-After: header */
|
||||||
|
|
||||||
/* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
|
/* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
|
||||||
and, 'conn_local_port' are copied over from the connectdata struct in
|
and, 'conn_local_port' are copied over from the connectdata struct in
|
||||||
@ -1090,7 +1091,6 @@ struct PureInfo {
|
|||||||
OpenSSL, GnuTLS, Schannel, NSS and GSKit
|
OpenSSL, GnuTLS, Schannel, NSS and GSKit
|
||||||
builds. Asked for with CURLOPT_CERTINFO
|
builds. Asked for with CURLOPT_CERTINFO
|
||||||
/ CURLINFO_CERTINFO */
|
/ CURLINFO_CERTINFO */
|
||||||
|
|
||||||
bit timecond:1; /* set to TRUE if the time condition didn't match, which
|
bit timecond:1; /* set to TRUE if the time condition didn't match, which
|
||||||
thus made the document NOT get fetched */
|
thus made the document NOT get fetched */
|
||||||
};
|
};
|
||||||
|
@ -178,7 +178,7 @@ test1540 test1541 \
|
|||||||
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
|
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
|
||||||
test1558 test1559 test1560 test1561 test1562 test1563 \
|
test1558 test1559 test1560 test1561 test1562 test1563 \
|
||||||
\
|
\
|
||||||
test1590 test1591 test1592 test1593 \
|
test1590 test1591 test1592 test1593 test1594 \
|
||||||
\
|
\
|
||||||
test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \
|
test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \
|
||||||
test1608 test1609 test1620 test1621 \
|
test1608 test1609 test1620 test1621 \
|
||||||
|
52
tests/data/test1594
Normal file
52
tests/data/test1594
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
HTTP replaced headers
|
||||||
|
CURLOPT_TIMECONDITION
|
||||||
|
If-Modified-Since
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 503 Error
|
||||||
|
Date: Thu, 11 Jul 2019 02:26:59 GMT
|
||||||
|
Server: test-server/swsclose
|
||||||
|
Retry-After: 22
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP Retry-After header parsing and extraction
|
||||||
|
</name>
|
||||||
|
<tool>
|
||||||
|
lib1594
|
||||||
|
</tool>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/1594
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /1594 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
<stdout>
|
||||||
|
Retry-After: 22
|
||||||
|
</stdout>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
51
tests/data/test1595
Normal file
51
tests/data/test1595
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
HTTP replaced headers
|
||||||
|
CURLOPT_TIMECONDITION
|
||||||
|
If-Modified-Since
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 503 Error
|
||||||
|
Date: Thu, 11 Jul 2019 02:26:59 GMT
|
||||||
|
Server: test-server/swsclose
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP Retry-After header extraction (without header)
|
||||||
|
</name>
|
||||||
|
<tool>
|
||||||
|
lib1594
|
||||||
|
</tool>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/1595
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /1595 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
<stdout>
|
||||||
|
Retry-After: 0
|
||||||
|
</stdout>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
52
tests/data/test1596
Normal file
52
tests/data/test1596
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
HTTP replaced headers
|
||||||
|
CURLOPT_TIMECONDITION
|
||||||
|
If-Modified-Since
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 503 Error
|
||||||
|
Date: Thu, 11 Jul 2019 02:26:59 GMT
|
||||||
|
Server: test-server/swsclose
|
||||||
|
Retry-After: Thu, 11 Jul 2024 02:26:59 GMT
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP Retry-After header parsing using a date
|
||||||
|
</name>
|
||||||
|
<tool>
|
||||||
|
lib1596
|
||||||
|
</tool>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/1596
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /1596 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
<stdout>
|
||||||
|
Retry-After: 172066
|
||||||
|
</stdout>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
@ -32,7 +32,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
|
|||||||
lib1540 lib1541 \
|
lib1540 lib1541 \
|
||||||
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
|
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
|
||||||
lib1558 lib1559 lib1560 \
|
lib1558 lib1559 lib1560 \
|
||||||
lib1591 lib1592 lib1593 \
|
lib1591 lib1592 lib1593 lib1594 lib1596 \
|
||||||
lib1900 lib1905 lib1906 \
|
lib1900 lib1905 lib1906 \
|
||||||
lib2033
|
lib2033
|
||||||
|
|
||||||
@ -544,6 +544,13 @@ lib1592_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1592
|
|||||||
lib1593_SOURCES = lib1593.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
lib1593_SOURCES = lib1593.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
lib1593_LDADD = $(TESTUTIL_LIBS)
|
lib1593_LDADD = $(TESTUTIL_LIBS)
|
||||||
|
|
||||||
|
lib1594_SOURCES = lib1594.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
|
lib1594_LDADD = $(TESTUTIL_LIBS)
|
||||||
|
|
||||||
|
lib1596_SOURCES = lib1594.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
|
lib1596_LDADD = $(TESTUTIL_LIBS)
|
||||||
|
lib1596_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1596
|
||||||
|
|
||||||
lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
lib1900_LDADD = $(TESTUTIL_LIBS)
|
lib1900_LDADD = $(TESTUTIL_LIBS)
|
||||||
lib1900_CPPFLAGS = $(AM_CPPFLAGS)
|
lib1900_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
66
tests/libtest/lib1594.c
Normal file
66
tests/libtest/lib1594.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* Testing Retry-After header parser */
|
||||||
|
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
int test(char *URL)
|
||||||
|
{
|
||||||
|
struct curl_slist *header = NULL;
|
||||||
|
curl_off_t retry;
|
||||||
|
CURL *curl = NULL;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
|
easy_init(curl);
|
||||||
|
|
||||||
|
easy_setopt(curl, CURLOPT_URL, URL);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
if(res)
|
||||||
|
goto test_cleanup;
|
||||||
|
|
||||||
|
res = curl_easy_getinfo(curl, CURLINFO_RETRY_AFTER, &retry);
|
||||||
|
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:
|
||||||
|
|
||||||
|
/* always cleanup */
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_slist_free_all(header);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user