diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2022-07-01 17:46:36 +0200 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2022-07-11 11:29:13 +0200 |
commit | fb60393dbfb14cf7bf927af44be9b89d7a5ae203 (patch) | |
tree | 52d32209bc14ccf59b9ab6f98393939f7245d9cc /crypto/http/http_client.c | |
parent | d15d29f2b594837475a2abe9265f95e11fab6d26 (diff) |
http_client.c: fix calculation of Content-Length in set1_content()
Work around an inconsistency in the implementations of BIO_CTRL_INFO.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/18701)
(cherry picked from commit 243465fd556837402bff52b7bf3d59420b68a02e)
Diffstat (limited to 'crypto/http/http_client.c')
-rw-r--r-- | crypto/http/http_client.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index 9f4555280c..08e726013c 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -267,6 +267,7 @@ static int set1_content(OSSL_HTTP_REQ_CTX *rctx, const char *content_type, BIO *req) { long req_len; + FILE *fp = NULL; if (rctx == NULL || (req == NULL && content_type != NULL)) { ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); @@ -290,14 +291,29 @@ static int set1_content(OSSL_HTTP_REQ_CTX *rctx, && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0) return 0; - /* streaming BIO may not support querying size */ - if (((req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL)) <= 0 - || BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) > 0) - && BIO_up_ref(req)) { - rctx->req = req; - return 1; + /* + * BIO_CTRL_INFO yields the data length at least for memory BIOs, but for + * file-based BIOs it gives the current position, which is not what we need. + */ + if (BIO_get_fp(req, &fp) == 1) { + fseek(fp, 0, SEEK_END); + req_len = ftell(fp); + fseek(fp, 0, SEEK_SET); + } else { + req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL); + /* + * Streaming BIOs likely will not support querying the size at all, + * and we assume we got a correct value if req_len > 0. + */ } - return 0; + if ((fp != NULL /* definitely correct req_len */ || req_len > 0) + && BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) < 0) + return 0; + + if (!BIO_up_ref(req)) + return 0; + rctx->req = req; + return 1; } int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type, |