Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2021-11-25 11:47:06 +0300
committerDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2021-11-25 11:47:06 +0300
commit699215ede1dbfc7d64ca20181a86124f1fe06076 (patch)
treedfbe732c57476aa66816b7b5c9141f35fca4c6da /src/libs/zbxembed
parent1fdf0ec1f9f901793b8f2f85ddd07af571c9a93a (diff)
........S. [ZBX-19806] added support of multiple header fields in JS method getHeaders()
Diffstat (limited to 'src/libs/zbxembed')
-rw-r--r--src/libs/zbxembed/httprequest.c166
1 files changed, 151 insertions, 15 deletions
diff --git a/src/libs/zbxembed/httprequest.c b/src/libs/zbxembed/httprequest.c
index 8ad63a2750a..2e27278f51e 100644
--- a/src/libs/zbxembed/httprequest.c
+++ b/src/libs/zbxembed/httprequest.c
@@ -25,6 +25,7 @@
#include "httprequest.h"
#include "embed.h"
#include "duktape.h"
+#include "zbxalgo.h"
#ifdef HAVE_LIBCURL
@@ -440,6 +441,32 @@ static duk_ret_t es_httprequest_status(duk_context *ctx)
/******************************************************************************
* *
+ * Function: parse_header *
+ * *
+ * Purpose: retrives value of a header *
+ * *
+ * Parameters: header - [IN] the http header to extract value from *
+ * value_out - [OUT] the value *
+ * *
+ ******************************************************************************/
+static int parse_header(char *header, char **value_out)
+{
+ char *value;
+
+ if (NULL == (value = strchr(header, ':')))
+ return FAIL;
+
+ *value++ = '\0';
+ while (' ' == *value || '\t' == *value)
+ value++;
+
+ *value_out = value;
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
* Function: es_obj_put_http_header *
* *
* Purpose: puts http header <field>: <value> as object property/value *
@@ -453,13 +480,9 @@ static void es_put_header(duk_context *ctx, int idx, char *header)
{
char *value;
- if (NULL == (value = strchr(header, ':')))
+ if (FAIL == parse_header(header, &value))
return;
- *value++ = '\0';
- while (' ' == *value || '\t' == *value)
- value++;
-
duk_push_string(ctx, value);
/* duk_put_prop_string() throws error on failure, no need to check return code */
@@ -468,19 +491,18 @@ static void es_put_header(duk_context *ctx, int idx, char *header)
/******************************************************************************
* *
- * Function: es_httprequest_get_headers *
+ * Function: get_headers_as_strings *
* *
- * Purpose: CurlHttpRequest.GetHeaders method *
+ * Purpose: retrieve headers from request in form of arrays *
+ * *
+ * Parameters: ctx - [IN] the duktape context *
+ * request - [IN] the request to retrieve headers from *
* *
******************************************************************************/
-static duk_ret_t es_httprequest_get_headers(duk_context *ctx)
+static duk_ret_t get_headers_as_strings(duk_context *ctx, zbx_es_httprequest_t *request)
{
- zbx_es_httprequest_t *request;
- duk_idx_t idx;
char *ptr, *header;
-
- if (NULL == (request = es_httprequest(ctx)))
- return duk_error(ctx, DUK_RET_EVAL_ERROR, "internal scripting error: null object");
+ duk_idx_t idx;
idx = duk_push_object(ctx);
@@ -496,6 +518,120 @@ static duk_ret_t es_httprequest_get_headers(duk_context *ctx)
return 1;
}
+typedef struct
+{
+ char *name;
+ zbx_vector_str_t values;
+}
+zbx_cached_header_t;
+
+static void cached_headers_free(zbx_cached_header_t *header)
+{
+ zbx_free(header->name);
+ zbx_vector_str_clear(&header->values);
+ zbx_vector_str_destroy(&header->values);
+ zbx_free(header);
+}
+
+static duk_ret_t get_headers_as_arrays(duk_context *ctx, zbx_es_httprequest_t *request)
+{
+ char *ptr, *header;
+ zbx_vector_ptr_t headers;
+ duk_idx_t idx;
+
+ zbx_vector_ptr_create(&headers);
+
+ idx = duk_push_object(ctx);
+
+ if (0 == request->headers_in_offset)
+ goto out;
+
+ for (ptr = request->headers_in; NULL != (header = zbx_http_parse_header(&ptr)); )
+ {
+ char *value;
+ zbx_cached_header_t *existing_header = NULL;
+
+ if (FAIL == parse_header(header, &value))
+ {
+ goto skip;
+ }
+
+ for (int j = 0; j < headers.values_num; j++) {
+ zbx_cached_header_t *h = (zbx_cached_header_t*)headers.values[j];
+
+ if (0 == strcmp(header, h->name))
+ {
+ existing_header = h;
+ break;
+ }
+ }
+
+ if (existing_header != NULL) {
+ zbx_vector_str_append(&existing_header->values, value);
+ }
+ else {
+ zbx_cached_header_t *cached_header;
+
+ cached_header = zbx_malloc(NULL, sizeof(zbx_cached_header_t));
+
+ cached_header->name = zbx_strdup(NULL, header);
+ zbx_vector_str_create(&cached_header->values);
+ zbx_vector_str_append(&cached_header->values, value);
+ zbx_vector_ptr_append(&headers, cached_header);
+ }
+skip:
+ zbx_free(header);
+ }
+
+ for (int i = 0; i < headers.values_num; i++) {
+ zbx_cached_header_t *h = (zbx_cached_header_t*)headers.values[i];
+ duk_idx_t arr_idx;
+
+ arr_idx = duk_push_array(ctx);
+
+ for (int j = 0; j < h->values.values_num; j++)
+ {
+ duk_push_string(ctx, h->values.values[j]);
+ duk_put_prop_index(ctx, arr_idx, j);
+ }
+
+ (void)duk_put_prop_string(ctx, idx, h->name);
+ }
+
+out:
+ zbx_vector_ptr_clear_ext(&headers, (zbx_mem_free_func_t)cached_headers_free);
+ zbx_vector_ptr_destroy(&headers);
+ return 1;
+}
+
+/******************************************************************************
+ * *
+ * Function: es_httprequest_get_headers *
+ * *
+ * Purpose: CurlHttpRequest.GetHeaders method *
+ * *
+ ******************************************************************************/
+static duk_ret_t es_httprequest_get_headers(duk_context *ctx)
+{
+ zbx_es_httprequest_t *request;
+ duk_idx_t idx;
+
+ if (NULL == (request = es_httprequest(ctx)))
+ return duk_error(ctx, DUK_RET_EVAL_ERROR, "internal scripting error: null object");
+
+ if (0 == duk_is_null_or_undefined(ctx, 0))
+ {
+ duk_bool_t as_array;
+
+ as_array = duk_to_boolean(ctx, 0);
+
+ if (0 != as_array)
+ return get_headers_as_arrays(ctx, request);
+ }
+
+ return get_headers_as_strings(ctx, request);
+}
+
/******************************************************************************
* *
* Function: es_httprequest_set_httpauth *
@@ -563,7 +699,7 @@ static const duk_function_list_entry curlhttprequest_methods[] = {
{"Delete", es_httprequest_delete, 2},
{"Status", es_httprequest_status, 0},
{"SetProxy", es_httprequest_set_proxy, 1},
- {"GetHeaders", es_httprequest_get_headers, 0},
+ {"GetHeaders", es_httprequest_get_headers, 1},
{"SetHttpAuth", es_httprequest_set_httpauth, 3},
{NULL, NULL, 0}
};
@@ -577,7 +713,7 @@ static const duk_function_list_entry httprequest_methods[] = {
{"delete", es_httprequest_delete, 2},
{"getStatus", es_httprequest_status, 0},
{"setProxy", es_httprequest_set_proxy, 1},
- {"getHeaders", es_httprequest_get_headers, 0},
+ {"getHeaders", es_httprequest_get_headers, 1},
{"setHttpAuth", es_httprequest_set_httpauth, 3},
{NULL, NULL, 0}
};