diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2021-11-29 10:07:08 +0100 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2021-12-09 18:11:52 +0100 |
commit | 93838762b406efe3aad9c807a0fd1f48e6efe3ab (patch) | |
tree | 611676815a63a31a4c33c561e91d37c5c0875783 /crypto/http | |
parent | f2f2ac88499ad58546f9c5b19ebc0b6eddf0b49f (diff) |
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)
(cherry picked from commit f0d5a3b6ea1bbe4e5dac5b69d853c015db635621)
Diffstat (limited to 'crypto/http')
-rw-r--r-- | crypto/http/http_client.c | 19 | ||||
-rw-r--r-- | crypto/http/http_err.c | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index 23677ca12f..7f8d8fc8d7 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -464,6 +464,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. @@ -1081,6 +1096,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); @@ -1111,7 +1127,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), |