summaryrefslogtreecommitdiffstats
path: root/crypto/http/http_client.c
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2022-07-01 17:46:36 +0200
committerDr. David von Oheimb <dev@ddvo.net>2022-07-11 11:29:13 +0200
commitfb60393dbfb14cf7bf927af44be9b89d7a5ae203 (patch)
tree52d32209bc14ccf59b9ab6f98393939f7245d9cc /crypto/http/http_client.c
parentd15d29f2b594837475a2abe9265f95e11fab6d26 (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.c30
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,