summaryrefslogtreecommitdiff
path: root/crypto/http
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-11-29 10:07:08 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-12-09 18:10:07 +0100
commitf0d5a3b6ea1bbe4e5dac5b69d853c015db635621 (patch)
tree30cf3aa6134ba049459b4b4d5cbb65c43cedd5e0 /crypto/http
parenta3ea35c2936acbe6a53b1d52d2d7addbfb6bbd5a (diff)
downloadopenssl-new-f0d5a3b6ea1bbe4e5dac5b69d853c015db635621.tar.gz
OSSL_HTTP_get(): Fix timeout handling on redirection
Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17190)
Diffstat (limited to 'crypto/http')
-rw-r--r--crypto/http/http_client.c19
-rw-r--r--crypto/http/http_err.c1
2 files changed, 19 insertions, 1 deletions
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index d8e54c03a9..a85bfcec42 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -463,6 +463,21 @@ static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len)
return 1;
}
+static int may_still_retry(time_t max_time, int *ptimeout)
+{
+ time_t time_diff, now = time(NULL);
+
+ if (max_time != 0) {
+ if (max_time < now) {
+ ERR_raise(ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT);
+ return 0;
+ }
+ time_diff = max_time - now;
+ *ptimeout = time_diff > INT_MAX ? INT_MAX : (int)time_diff;
+ }
+ return 1;
+}
+
/*
* Try exchanging request and response via HTTP on (non-)blocking BIO in rctx.
* Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry.
@@ -1071,6 +1086,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
int use_ssl;
OSSL_HTTP_REQ_CTX *rctx;
BIO *resp = NULL;
+ time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
if (url == NULL) {
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
@@ -1101,7 +1117,8 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
}
OPENSSL_free(path);
if (resp == NULL && redirection_url != NULL) {
- if (redirection_ok(++n_redirs, current_url, redirection_url)) {
+ if (redirection_ok(++n_redirs, current_url, redirection_url)
+ && may_still_retry(max_time, &timeout)) {
(void)BIO_reset(bio);
OPENSSL_free(current_url);
current_url = redirection_url;
diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c
index b2f2cfb187..332ad926d3 100644
--- a/crypto/http/http_err.c
+++ b/crypto/http/http_err.c
@@ -55,6 +55,7 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
"response line too long"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
"response parse error"},
+ {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RETRY_TIMEOUT), "retry timeout"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_CANCELED_CONNECTION),
"server canceled connection"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED),