112 lines
3.6 KiB
Diff
112 lines
3.6 KiB
Diff
|
From 13d720de13e490850c1139eea865bcd5195a2630 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||
|
Date: Wed, 15 Mar 2017 15:15:08 +0100
|
||
|
Subject: [PATCH 91/97] secrets: always add Content-Length header
|
||
|
|
||
|
If custodia server does not reply with Content-Length header, curl may
|
||
|
wait for non-existing body of http reply if such body does not exist
|
||
|
(for example during POST operation when creating a container).
|
||
|
|
||
|
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||
|
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||
|
---
|
||
|
src/responder/secrets/providers.c | 72 ++++++++++++++++++++++++++++++++++++---
|
||
|
1 file changed, 68 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c
|
||
|
index 80a443d91135447ec8ce8d424b692a6d7e26a907..a27fb720b394e7c76d1b65f656146bcd00755449 100644
|
||
|
--- a/src/responder/secrets/providers.c
|
||
|
+++ b/src/responder/secrets/providers.c
|
||
|
@@ -388,20 +388,84 @@ int sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
|
||
|
return EOK;
|
||
|
}
|
||
|
|
||
|
+static errno_t
|
||
|
+sec_http_iobuf_split(struct sss_iobuf *response,
|
||
|
+ const char **headers,
|
||
|
+ const char **body)
|
||
|
+{
|
||
|
+ const char *data = (const char *)sss_iobuf_get_data(response);
|
||
|
+ char *delim;
|
||
|
+
|
||
|
+ /* The last header ends with \r\n and then comes \r\n again as a separator
|
||
|
+ * of body from headers. We can use this to find this point. */
|
||
|
+ delim = strstr(data, "\r\n\r\n");
|
||
|
+ if (delim == NULL) {
|
||
|
+ return EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Skip to the body delimiter. */
|
||
|
+ delim = delim + sizeof("\r\n") - 1;
|
||
|
+
|
||
|
+ /* Replace \r\n with zeros turning data into:
|
||
|
+ * from HEADER\r\nBODY into HEADER\0\0BODY format. */
|
||
|
+ delim[0] = '\0';
|
||
|
+ delim[1] = '\0';
|
||
|
+
|
||
|
+ /* Split the buffer. */
|
||
|
+ *headers = data;
|
||
|
+ *body = delim + 2;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static const char *
|
||
|
+sec_http_iobuf_add_content_length(TALLOC_CTX *mem_ctx,
|
||
|
+ const char *headers,
|
||
|
+ size_t body_len)
|
||
|
+{
|
||
|
+ /* If Content-Length is already present we do nothing. */
|
||
|
+ if (strstr(headers, "Content-Length:") != NULL) {
|
||
|
+ return headers;
|
||
|
+ }
|
||
|
+
|
||
|
+ return talloc_asprintf(mem_ctx, "%sContent-Length: %zu\r\n",
|
||
|
+ headers, body_len);
|
||
|
+}
|
||
|
+
|
||
|
errno_t sec_http_reply_iobuf(TALLOC_CTX *mem_ctx,
|
||
|
struct sec_data *reply,
|
||
|
int response_code,
|
||
|
struct sss_iobuf *response)
|
||
|
{
|
||
|
+ const char *headers;
|
||
|
+ const char *body;
|
||
|
+ size_t body_len;
|
||
|
+ errno_t ret;
|
||
|
+
|
||
|
DEBUG(SSSDBG_TRACE_LIBS, "HTTP reply %d\n", response_code);
|
||
|
|
||
|
- reply->data = (char *)sss_iobuf_get_data(response);
|
||
|
- reply->length = sss_iobuf_get_len(response);
|
||
|
+ ret = sec_http_iobuf_split(response, &headers, &body);
|
||
|
+ if (ret != EOK) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||
|
+ "Unexpected HTTP reply, returning what we got from server\n");
|
||
|
+ reply->data = (char *)sss_iobuf_get_data(response);
|
||
|
+ reply->length = sss_iobuf_get_len(response);
|
||
|
|
||
|
- talloc_steal(mem_ctx, reply->data);
|
||
|
+ return EOK;
|
||
|
+ }
|
||
|
|
||
|
+ /* Add Content-Length header if not present so client does not await
|
||
|
+ * not-existing incoming data. */
|
||
|
+ body_len = strlen(body);
|
||
|
+ headers = sec_http_iobuf_add_content_length(mem_ctx, headers, body_len);
|
||
|
+ if (headers == NULL) {
|
||
|
+ return ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ reply->length = strlen(headers) + sizeof("\r\n") - 1 + body_len;
|
||
|
+ reply->data = talloc_asprintf(mem_ctx, "%s\r\n%s", headers, body);
|
||
|
if (reply->data == NULL) {
|
||
|
- return EINVAL;
|
||
|
+ return ENOMEM;
|
||
|
}
|
||
|
|
||
|
return EOK;
|
||
|
--
|
||
|
2.12.2
|
||
|
|