The branch master has been updated via f0d5a3b6ea1bbe4e5dac5b69d853c015db635621 (commit) from a3ea35c2936acbe6a53b1d52d2d7addbfb6bbd5a (commit)
- Log ----------------------------------------------------------------- commit f0d5a3b6ea1bbe4e5dac5b69d853c015db635621 Author: Dr. David von Oheimb <david.von.ohe...@siemens.com> Date: Mon Nov 29 10:07:08 2021 +0100 OSSL_HTTP_get(): Fix timeout handling on redirection Reviewed-by: Paul Dale <pa...@openssl.org> Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17190) ----------------------------------------------------------------------- Summary of changes: crypto/err/openssl.txt | 1 + crypto/http/http_client.c | 19 ++++++++++++++++++- crypto/http/http_err.c | 1 + include/openssl/httperr.h | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 777a0de19d..6e75af9b8b 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -779,6 +779,7 @@ HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error +HTTP_R_RETRY_TIMEOUT:129:retry timeout HTTP_R_SERVER_CANCELED_CONNECTION:127:server canceled connection HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported 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), diff --git a/include/openssl/httperr.h b/include/openssl/httperr.h index b639ef0051..ee08959203 100644 --- a/include/openssl/httperr.h +++ b/include/openssl/httperr.h @@ -44,6 +44,7 @@ # define HTTP_R_REDIRECTION_NOT_ENABLED 116 # define HTTP_R_RESPONSE_LINE_TOO_LONG 113 # define HTTP_R_RESPONSE_PARSE_ERROR 104 +# define HTTP_R_RETRY_TIMEOUT 129 # define HTTP_R_SERVER_CANCELED_CONNECTION 127 # define HTTP_R_SOCK_NOT_SUPPORTED 122 # define HTTP_R_STATUS_CODE_UNSUPPORTED 114