From patchwork Thu Sep 9 13:34:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sava Jakovljev X-Patchwork-Id: 1526206 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20210112 header.b=VQt//RWZ; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2607:f8b0:4864:20::b39; helo=mail-yb1-xb39.google.com; envelope-from=swupdate+bncbaabba435ceqmgqedaddtny@googlegroups.com; receiver=) Received: from mail-yb1-xb39.google.com (mail-yb1-xb39.google.com [IPv6:2607:f8b0:4864:20::b39]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H50P70jr6z9tkM for ; Thu, 9 Sep 2021 23:35:05 +1000 (AEST) Received: by mail-yb1-xb39.google.com with SMTP id b9-20020a5b07890000b0290558245b7eabsf2381367ybq.10 for ; Thu, 09 Sep 2021 06:35:05 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1631194500; cv=pass; d=google.com; s=arc-20160816; b=dy6MJhPcgXwQFGDzJuIDyC4pXVGhQnUfQIo1fWHdxzLhYv0AFUrfiI43rR315M0lnT uyynNmrm7XeV2v67DHh+zfZ3/d5iS1pwGq9QeqDENLBxFVWei+Haydx02Sdf4BNKNdPi ccswKAPbZYtm5pyt7SYmyatzIiYWNDXUQQwnU8ADM3V4Qm8ULcyEn2Xde8N8hpBVk6Sl ZhWp30d4ncEoOtXXo3dRT4HRlPokAExVC/N873ZqwAc88r0af/0TrJz2a8wN1twe6VlV xXOhPclNY3wzVpMjFGXtV+g8rDRsycaA03PZFe3YUa8sXSFd7UrnWbvm6U1wY3LK0gjg Jh4Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:message-id:date :subject:cc:to:from:sender:dkim-signature; bh=fpzQRz7FrEPcKhdLqZw0x+SCCmzLEIYwU9Fp+MFuEb0=; b=EgUTHshaPyNKNdAwPspd8WkkHwRMxJK3JS8KWwmw/E7Ytr1i8QZ1NXlroOTDsG4a/U RzYjJ44MfNXwDlt+noo/SmfwlMqeyUeuvEAho3XibU4o6SVZA047CuEU+XXZkccD4V6I GeHFqUiaOYwIXS03XrMj+VCVbibD+VusORXLBqVioAizTKSXIGGNwcKhiQYlKIfcnPcG FscRta8TuFZZfnjEjWBmhOJHU2vkD+ICoizVeoP3jCTtsPfKQn1f3snIHv+wUYJYrl7E jMVQF6lcW9qXgmIG3nGD3O5ApAx9ZjHKtfQBfIq6KDEtF+nOfwckNSkoMzOQwjQv12/I u2Iw== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=VlMULg6t; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.136.201 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=teufel.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=fpzQRz7FrEPcKhdLqZw0x+SCCmzLEIYwU9Fp+MFuEb0=; b=VQt//RWZdKVhQcN6xAR691xe+lQVcX+uhT3CfyxBFBgsYAZLPqrqBM/1wL1LnRDer+ B6nD2IAX8Jz09VdfAcOmOR8O+NAQPHm4O67lrx7BjjQVI4gHLqlVf65swaty97mlWAKT gyu1amPOkmldNFWRerzh3LQO7wPmMa/TPFExpT5LCQjIM2M2c/XaN/UfsqUdKp8rZgVp /bfS95+EJ8c+tM6Kg0KuZpzN47a2QDjUODULay0bIOYPZMv9Zpm+gp2QMst3q9ogh0BN M+BkRLWIviCi+ltmBq/rKZ+rtWYSz8wIFoSyVoLpH0nyvgtsydO37439FEqoXFeQbiqn CIGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=sender:x-gm-message-state:from:to:cc:subject:date:message-id :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-subscribe:list-unsubscribe; bh=fpzQRz7FrEPcKhdLqZw0x+SCCmzLEIYwU9Fp+MFuEb0=; b=y/z07rIqi2iKF0ASzMCv8urXFNiYwlI7fdy12v05Zl1T7Df5h4ZNSKaUbBhCRu/Odb pRjofzmFyKVVxC6GxqtueTEtcnj4aDQLfDXuNqWAhCMsW9EObSamv8R/8w16gxZJmmf7 8TIUrN2i5RJVqQXDlzlv+fLoyv31hLSbisx//vpBq6peODkZ5TxTUTDyCByJU85KmAQ9 f6i00+ng0/eSKTl72BcNq6v8f9mAmgawVJr7EpJeH4Z5p+SdMSW3tM64oiKfMetOk9U2 xtrwo11yepVF4ayDRuvXf/xm2f1VqdsgagCsLpYpdD7bQVQTk7BM7gRx/WZJB2Ym/pTv CAbA== Sender: swupdate@googlegroups.com X-Gm-Message-State: AOAM533AxknSEBs0c+pDJbuNtulDq7agZoWPfZII+KsZMvACshGUHJ6Z uuXvHo1tK9zPnuSxMDviSSg= X-Google-Smtp-Source: ABdhPJxM89pTNOBtc4uFbOo4sg5aKIwbellzrJ72GOUgg+uuH+3GVBHD69FfdSW5SCJ/gHwpQ1pImw== X-Received: by 2002:a25:bbc4:: with SMTP id c4mr4101587ybk.114.1631194499908; Thu, 09 Sep 2021 06:34:59 -0700 (PDT) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a25:6e04:: with SMTP id j4ls1000022ybc.7.gmail; Thu, 09 Sep 2021 06:34:59 -0700 (PDT) X-Received: by 2002:a25:a527:: with SMTP id h36mr3908803ybi.326.1631194499484; Thu, 09 Sep 2021 06:34:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631194499; cv=none; d=google.com; s=arc-20160816; b=WZ7QorBK8vkQVdtMr358LC++Zw/Wlo+F/HBlxUWfvPkTHFm+p2a02mPD3MqNa3zriJ cBacK8tgEF2bI0UO9gLKtSzgCzFlvulUVzLM1uFaPY5l/f9lwRDpohRN+7PfkymKeWTs V8KGEbdcI3RTFiSpa39bwomeWxXCViJ+F/naihJE5WnFRX4Ai4Lc9XBddVtRy2Fl6C55 fN//UHycJ4LcGz2ravlD9o1lxXh7mgt4gs+d3DDYZzF6LES8zOnytkm22zG2Wk5q+sLE ByOwBZEbBff2dMB9foer82c1YUA9vJdZfjSqGJ89MDkQ5uO6x3FvH1vqZIYnFD2UXQb3 V0yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=dkim-signature:content-transfer-encoding:mime-version:message-id :date:subject:cc:to:from; bh=ZCwdwDAgYc7ZvvHNOR7yNdH6D3Ix1NFoRP/5Ofw3NH4=; b=q1p8Hb3MKfEyxpAFEPLSnkHwk3tZj6X4HMaGAN1WcxK9MaNOtr8V8DiDxY9rcW0iBp xhA9wRcsrS8mnud3KQw1WdMDKAkBpB4jifm9WShjKg2i2CXZqxZMKHg3DadJ66zp9WQX LzsQ+9PO9X0EeDSEoNR8JKZmGUZw2vCDt+xerVlWVXHSs+cloBgLWmN/5A5Ya9kA3+hI ERGKiEQxoLXpG4bXAZtm4tfV1myDXDJx7FXTvJESdTZBn26HCefjB6lA1dXqrKQOREn5 ONvSkLCfZCEI+xQbB4Fpi0esWxS7bYq1QXVkbhOmZvH20p5cky2tKVUCMg0QH23smUg7 ssZg== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=VlMULg6t; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.136.201 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=teufel.de Received: from mx-relay100-hz2.antispameurope.com (mx-relay100-hz2.antispameurope.com. [94.100.136.201]) by gmr-mx.google.com with ESMTPS id i18si144982ybj.4.2021.09.09.06.34.57 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Sep 2021 06:34:59 -0700 (PDT) Received-SPF: pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.136.201 as permitted sender) client-ip=94.100.136.201; Received: from unknown ([212.91.255.190]) by mx-relay100-hz2.antispameurope.com; Thu, 09 Sep 2021 15:34:53 +0200 From: Sava Jakovljev To: CC: Sava Jakovljev Subject: [swupdate] [PATCH v4] channel_curl: Add ability to define a set of custom HTTP headers Date: Thu, 9 Sep 2021 15:34:28 +0200 Message-ID: <20210909133428.338445-1-sava.jakovljev@teufel.de> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Originating-IP: [10.10.25.44] X-ClientProxiedBy: DNS-EX-01.teufel.local (10.10.0.80) To DNS-EX-02.teufel.local (10.10.0.81) X-C2ProcessedOrg: b93e13a0-e8da-4ba4-97b8-f14375b21c41 X-cloud-security-sender: sava.jakovljev@teufel.de X-cloud-security-recipient: swupdate@googlegroups.com X-cloud-security-Virusscan: CLEAN X-cloud-security-disclaimer: This E-Mail was scanned by E-Mailservice on mx-relay100-hz2.antispameurope.com with 855971603C9E X-cloud-security-connect: unknown[212.91.255.190], TLS=1, IP=212.91.255.190 X-cloud-security-Digest: 9d3d2b4b841d192adeb5a90d67efb8b1 X-cloud-security: scantime:4.421 X-Original-Sender: sava.jakovljev@teufel.de X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=VlMULg6t; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.136.201 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=teufel.de Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , * Expand Suricatta/Hawkbit client with ability to define a custom set of HTTP requests, defined through command line or configuration file, using 'a' short option or "custom-http-header" long option. Signed-off-by: Sava Jakovljev --- corelib/channel_curl.c | 8 +++++--- corelib/downloader.c | 3 ++- doc/source/swupdate.rst | 8 ++++++-- include/channel_curl.h | 3 ++- suricatta/server_general.c | 33 +++++++++++++++++++++++++++------ suricatta/server_general.h | 3 ++- suricatta/server_hawkbit.c | 27 ++++++++++++++++++++++++--- suricatta/server_hawkbit.h | 1 + 8 files changed, 69 insertions(+), 17 deletions(-) diff --git a/corelib/channel_curl.c b/corelib/channel_curl.c index e910f76..bc387d0 100644 --- a/corelib/channel_curl.c +++ b/corelib/channel_curl.c @@ -585,7 +585,7 @@ channel_op_res_t channel_set_options(channel_t *this, channel_data_t *channel_da goto cleanup; } - if (channel_data->headers) { + if (channel_data->received_headers) { /* * Setup supply request and receive reply HTTP headers. * A LIST_INIT()'d dictionary is expected at channel_data->headers. @@ -596,14 +596,16 @@ channel_op_res_t channel_set_options(channel_t *this, channel_data_t *channel_da CURLOPT_HEADERFUNCTION, channel_callback_headers) != CURLE_OK) || (curl_easy_setopt(channel_curl->handle, CURLOPT_HEADERDATA, - channel_data->headers) != CURLE_OK)) { + channel_data->received_headers) != CURLE_OK)) { result = CHANNEL_EINIT; goto cleanup; } + } + if (channel_data->headers_to_send) { struct dict_entry *entry; char *header; - LIST_FOREACH(entry, channel_data->headers, next) + LIST_FOREACH(entry, channel_data->headers_to_send, next) { if (ENOMEM_ASPRINTF == asprintf(&header, "%s: %s", diff --git a/corelib/downloader.c b/corelib/downloader.c index 437b36d..3d0a0a5 100644 --- a/corelib/downloader.c +++ b/corelib/downloader.c @@ -104,7 +104,8 @@ static channel_data_t channel_options = { .source = SOURCE_DOWNLOADER, .debug = false, .retries = DL_DEFAULT_RETRIES, - .low_speed_timeout = DL_LOWSPEED_TIME + .low_speed_timeout = DL_LOWSPEED_TIME, + .headers_to_send = NULL }; int start_download(const char *fname, int argc, char *argv[]) diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst index 317c54d..5b0c150 100644 --- a/doc/source/swupdate.rst +++ b/doc/source/swupdate.rst @@ -184,7 +184,7 @@ Images fully streamed --------------------- In case of remote update, SWUpdate extracts relevant images from the stream -and copies them into the directory pointed to by the environment variable +and copies them into the directory pointed to by the environment variable ``TMPDIR`` (if unset, to ``/tmp``) before calling the handlers. This guarantee that an update is initiated only if all parts are present and correct. However, on some systems with less resources, the amount of RAM @@ -652,6 +652,10 @@ Mandatory arguments are marked with '\*': | | | during this period - adapt this value to | | | | your use case! | +-------------------------+----------+--------------------------------------------+ +| -a | strings | Custom HTTP header with given name and | +| | | value to be sent with every HTTP request | +| | | made. | ++-------------------------+----------+--------------------------------------------+ systemd Integration @@ -706,7 +710,7 @@ files are also handed over on a "regular" start of SWUpdate via ``systemctl start swupdate.service``. Note that the socket paths in the two ``ListenStream=`` directives -have to match the socket paths ``CONFIG_SOCKET_CTRL_PATH`` and +have to match the socket paths ``CONFIG_SOCKET_CTRL_PATH`` and ``CONFIG_SOCKET_PROGRESS_PATH`` in SWUpdate's configuration. Here, the default socket path configuration is depicted. diff --git a/include/channel_curl.h b/include/channel_curl.h index 4de098e..6dabae6 100644 --- a/include/channel_curl.h +++ b/include/channel_curl.h @@ -72,5 +72,6 @@ typedef struct { struct swupdate_digest *dgst; char sha1hash[SWUPDATE_SHA_DIGEST_LENGTH * 2 + 1]; sourcetype source; - struct dict *headers; + struct dict *headers_to_send; + struct dict *received_headers; } channel_data_t; diff --git a/suricatta/server_general.c b/suricatta/server_general.c index 1d11ada..146f02c 100644 --- a/suricatta/server_general.c +++ b/suricatta/server_general.c @@ -453,8 +453,9 @@ static server_op_res_t server_get_deployment_info(channel_t *channel, channel_da */ channel_data->url= server_prepare_query(server_general.url, &server_general.configdata); - LIST_INIT(&server_general.httpheaders); - channel_data->headers = &server_general.httpheaders; + LIST_INIT(&server_general.received_httpheaders); + LIST_INIT(&server_general.httpheaders_to_send); + channel_data->received_headers = &server_general.received_httpheaders; result = map_http_retcode(channel->get(channel, (void *)channel_data)); @@ -462,12 +463,12 @@ static server_op_res_t server_get_deployment_info(channel_t *channel, channel_da free(channel_data->url); } - pollstring = dict_get_value(&server_general.httpheaders, "Retry-After"); + pollstring = dict_get_value(&server_general.received_httpheaders, "Retry-After"); if (pollstring) { server_set_polling_interval(pollstring); } - dict_drop_db(&server_general.httpheaders); + dict_drop_db(&server_general.received_httpheaders); return result; } @@ -522,7 +523,9 @@ void server_print_help(void) "\t -w, --retrywait Time to wait prior to retry and " "resume a download (default: %ds).\n" "\t -y, --proxy Use proxy. Either give proxy URL, else " - "{http,all}_proxy env is tried.\n", + "{http,all}_proxy env is tried.\n" + "\t -a, --custom-http-header Set custom HTTP header, " + "appended to every HTTP request being sent.", CHANNEL_DEFAULT_POLLING_INTERVAL, CHANNEL_DEFAULT_RESUME_TRIES, CHANNEL_DEFAULT_RESUME_DELAY); } @@ -608,6 +611,7 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) int choice = 0; LIST_INIT(&server_general.configdata); + LIST_INIT(&server_general.httpheaders_to_send); if (fname) { swupdate_cfg_handle handle; @@ -626,7 +630,7 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) /* reset to optind=1 to parse suricatta's argument vector */ optind = 1; opterr = 0; - while ((choice = getopt_long(argc, argv, "u:l:r:w:p:2:", + while ((choice = getopt_long(argc, argv, "u:l:r:w:p:2:a:", long_options, NULL)) != -1) { switch (choice) { case 'u': @@ -652,6 +656,21 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) SETSTRING(server_general.cached_file, optarg); break; /* Ignore not recognized options, they can be already parsed by the caller */ + case 'a': + if (optind >= argc) + return SERVER_EINIT; + + char *name = NULL; + SETSTRING(name, optarg); + char *value = NULL; + SETSTRING(value, argv[optind++]); + + if (dict_insert_value(&server_general.httpheaders_to_send, + name, + value) < 0) + return SERVER_EINIT; + + break; case '?': default: break; @@ -664,6 +683,8 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) return SERVER_EINIT; } + channel_data_defaults.headers_to_send = &server_general.httpheaders_to_send; + if (channel_curl_init() != CHANNEL_OK) return SERVER_EINIT; diff --git a/suricatta/server_general.h b/suricatta/server_general.h index 69345a1..d5d8d48 100644 --- a/suricatta/server_general.h +++ b/suricatta/server_general.h @@ -23,7 +23,8 @@ typedef struct { bool debug; char *cached_file; struct dict configdata; - struct dict httpheaders; + struct dict received_httpheaders; + struct dict httpheaders_to_send; update_state_t update_state; channel_t *channel; } server_general_t; diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c index 33d2eec..daa00f0 100644 --- a/suricatta/server_hawkbit.c +++ b/suricatta/server_hawkbit.c @@ -52,6 +52,7 @@ static struct option long_options[] = { {"cache", required_argument, NULL, '2'}, {"initial-report-resend-period", required_argument, NULL, 'm'}, {"connection-timeout", required_argument, NULL, 's'}, + {"custom-http-header", required_argument, NULL, 'a'}, {NULL, 0, NULL, 0}}; static unsigned short mandatory_argument_count = 0; @@ -132,7 +133,9 @@ static channel_data_t channel_data_defaults = {.debug = false, .nocheckanswer = false, .nofollow = false, .strictssl = true, - .connection_timeout = 0 + .connection_timeout = 0, + .headers_to_send = NULL, + .received_headers = NULL }; static struct timeval server_time; @@ -1602,7 +1605,9 @@ void server_print_help(void) "\t --cache Use cache file as starting SWU\n" "\t -m, --initial-report-resend-period Time to wait prior to retry " "sending initial state with '-c' option (default: %ds).\n" - "\t -s, --connection-timeout Set the server connection timeout (default: 300s).\n", + "\t -s, --connection-timeout Set the server connection timeout (default: 300s).\n" + "\t -a, --custom-http-header Set custom HTTP header, " + "appended to every HTTP request being sent.", CHANNEL_DEFAULT_POLLING_INTERVAL, CHANNEL_DEFAULT_RESUME_TRIES, CHANNEL_DEFAULT_RESUME_DELAY, INITIAL_STATUS_REPORT_WAIT_DELAY); @@ -1661,6 +1666,7 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) mandatory_argument_count = 0; LIST_INIT(&server_hawkbit.configdata); + LIST_INIT(&server_hawkbit.httpheaders); server_hawkbit.initial_report_resend_period = INITIAL_STATUS_REPORT_WAIT_DELAY; if (fname) { @@ -1677,6 +1683,9 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) */ read_module_settings(&handle, "hawkbit", server_hawkbit_settings, NULL); read_module_settings(&handle, "identify", settings_into_dict, &server_hawkbit.configdata); + + read_module_settings(&handle, "custom-http-headers", + settings_into_dict, &server_hawkbit.httpheaders); } swupdate_cfg_destroy(&handle); } @@ -1689,7 +1698,7 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) /* reset to optind=1 to parse suricatta's argument vector */ optind = 1; opterr = 0; - while ((choice = getopt_long(argc, argv, "t:i:c:u:p:xr:y::w:k:g:f:2:m:s:", + while ((choice = getopt_long(argc, argv, "t:i:c:u:p:xr:y::w:k:g:f:2:m:s:a:", long_options, NULL)) != -1) { switch (choice) { case 't': @@ -1782,6 +1791,16 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) channel_data_defaults.connection_timeout = (unsigned int)strtoul(optarg, NULL, 10); break; + case 'a': + if (optind >= argc) + return SERVER_EINIT; + + if (dict_insert_value(&server_hawkbit.httpheaders, + optarg, + argv[optind++]) < 0) + return SERVER_EINIT; + + break; /* Ignore not recognized options, they can be already parsed by the caller */ case '?': break; @@ -1799,6 +1818,8 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) return SERVER_EINIT; } + channel_data_defaults.headers_to_send = &server_hawkbit.httpheaders; + if (channel_curl_init() != CHANNEL_OK) return SERVER_EINIT; diff --git a/suricatta/server_hawkbit.h b/suricatta/server_hawkbit.h index aea4bb0..67f1c31 100644 --- a/suricatta/server_hawkbit.h +++ b/suricatta/server_hawkbit.h @@ -29,6 +29,7 @@ typedef struct { bool polling_interval_from_server; bool debug; struct dict configdata; + struct dict httpheaders; bool has_to_send_configData; char *configData_url; char *cancel_url;