From patchwork Thu Sep 2 10:04:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sava Jakovljev X-Patchwork-Id: 1523586 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=nnOXLOh7; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::23d; helo=mail-lj1-x23d.google.com; envelope-from=swupdate+bncbaabbv6dykeqmgqexqjs6wy@googlegroups.com; receiver=) Received: from mail-lj1-x23d.google.com (mail-lj1-x23d.google.com [IPv6:2a00:1450:4864:20::23d]) (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 4H0c4H0T5Sz9sCD for ; Thu, 2 Sep 2021 20:05:17 +1000 (AEST) Received: by mail-lj1-x23d.google.com with SMTP id q9-20020a2e9689000000b001b964fa10b3sf446217lji.18 for ; Thu, 02 Sep 2021 03:05:17 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1630577112; cv=pass; d=google.com; s=arc-20160816; b=ntW/D+s7zv2ktlKpGuLXgHSDDmDdutga+MYr+FgxKMeTpKst/M2/Vabp/zjn145U6B RKEhgLom3CqknrCA0aigmTrPiKhee6NMxGav39Op3cQZycS+mITvsgwxED6+1cT+I7yZ U+RFq1OjUy7EcpPLpumMdsgd5gD34F2dU+EJhPzVhkyKof+WBtoujLe/X9Iw+RWS+Zmi f5dK2TZCnogVUaPGLJ/lf+Z82bh4kif9E7h3MUM2fCAozFjP025ndPjOTNUWiq0Tzkb9 2Ss2gJ9aKZi7ev9RBEnHRFXA8cXCnyxh5wJzymUe5k5PUezSemoLn63kbJ5XnWn1b5gJ CBWw== 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=O0W4j5K1pza+iw32QHduikznHWTr76f4pIC/NuCpQEM=; b=QZM2oyP59KM15/C73GKPatPLjkBwHWzyHV5lZ7UhS12yetGneUrDi1wcUqyK2sao0H sSHsyWqDxpFZyp2z2kZSyZ+z8brKCbcCrmcAJ3FkEzCIBxQpiO8wmKFTSLWM0JHT7DPN tDNxPXRIDNg51T47BLy6a69I8XAOb7uWIhWgfik8KnE/vPm5YRkvBgNU6kss1+SLAhXO oON4koSz01wMV3Zxo474D9JWO5FAJIg8eulkhkemoW31IZ8PYtbAyPAuVm1MzAFpWfUE ifAouxSYqGvlIPrT6YAXIzCVAwJ2+8RgZ7HN0GGJTUn99ADrIpEh38jQTBJF5g/MJU1y V3zQ== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b="c+Hs/Xbt"; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 83.246.65.91 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=O0W4j5K1pza+iw32QHduikznHWTr76f4pIC/NuCpQEM=; b=nnOXLOh7mbHz2K0E7ucEIfkyO8XeW35a+Uu2JQZabP87+YMi1K5Puhkra+QcMWbOok mH0YkzdVJPDXg/ktNvLG4a3xnAU2XCjuP8tIT4bV+KlLJnDnwuk8SZJF9sPjtwNgNRDN f2Hw7PSwCOvDb+F97NlK64T0+n4kFckMPDDG1pVr8+1si4rrhYreFXgIqkzuK60AYmvS pUO1X4R37erKPn3ZS8iYxKuPpgmwLWjPNSLOOqM2ZF2Znylx/X6TGiRj4ruVmbs2nAGW mD22WaePWVJtQ1FFAsOlotv9Rx8yPEtjS9Ji/ykAbosaoH2cM1MRrFSkySrrTfHTwJm0 IQoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; 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=O0W4j5K1pza+iw32QHduikznHWTr76f4pIC/NuCpQEM=; b=Y1VME2ON9HUovV+LPovh0BcWXv09/EoBpzILQzhuibidZ8fX6duf7ugTow587PVp4M Ny0JI8YitliuK0HlPgo0cgTF7O1O+mmdVEdGXtyLLHDGaXVRsKkbXIF/xlULNIw03Act ko0CLx0GI10jc20UYdOQTeZQdiI8SJ+Y2yAuyAzev/58cFCorfVhXojMjlU7tmNfC4qG WHUbBU7NlUn9umHxvSn0xU1Ubn0MzNZE1vioFlYhpZ443P1+naw1J6BI/fEUKTvuMy+D AFNIqXGh5iedlUA6G/7goGrbHw3oVT9rTNLe3qO3qx1tyscPsxD2F9ojRP+/7kJdhWe8 8mmw== Sender: swupdate@googlegroups.com X-Gm-Message-State: AOAM532AZmVJmFkfoRJ5yKtQ3h5XcpW2I0V9SjhslVGw8B/SobJFbC9B mIN987gKpyi2q8eQs77B+ag= X-Google-Smtp-Source: ABdhPJxfmqHugi+i45I8rpxI7I0eiuopfgeesX1vMGUfL98LgOT62YC5lYTiSZ30mVdbsjDgjA609A== X-Received: by 2002:a2e:89d8:: with SMTP id c24mr1813103ljk.419.1630577111858; Thu, 02 Sep 2021 03:05:11 -0700 (PDT) X-BeenThere: swupdate@googlegroups.com Received: by 2002:ac2:55b7:: with SMTP id y23ls434301lfg.1.gmail; Thu, 02 Sep 2021 03:05:10 -0700 (PDT) X-Received: by 2002:ac2:598a:: with SMTP id w10mr2008794lfn.179.1630577110898; Thu, 02 Sep 2021 03:05:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630577110; cv=none; d=google.com; s=arc-20160816; b=KOlabUowKpEMlR06oFz9SESDCIcvg4L7SaGCEiAr5+xrMjKlmEBayCk1M54/znRI6g BfqfJ3pQ7+lfZyJFQmIXuLwoqCkg59m/Y/q3RxWRwlQyhpr0m2xQq7Wqyr1ZfL2srOIR np/iW3P70vZFFZ9j4viP7D2ohekovpDeouc5v7sPmsd4fE1cmi4qfeYDDC3AVs2fcNes j4MDZDQFD6J7qLOa1x2xgqm7s9w+TaZvNaA6xkIqTvEvKwuFsAYO1lg7qR9SMxDuZk4m ZlTvH1l3v9Dg03CNcH3b0v1lBY1lA4FgydrF5fLpyUW8Y55K4Q/AzQGko0gifRaSfHWu YWDQ== 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=vduLcDs39gOsOPfz+XE/m8G8NA//11jAkygNlAQq/zk=; b=jQ0ENVE7z++DXA8OwoDpqdV6kvJ6NpZEbJrXdFtxNk9+qO10Ww54acyScAqdI6cXQn mBGoaQjRp2PQ7tJnKczsRt8KozkfG6XugcUMnMkjqeKGks1UDfhf/4mphZduMzFJfSa+ XKyfKgPHjfd5UszONnvKutYg/FLdY8mbtz3oO0xzOIK5j3ApoFIbZt1n2KNrXGEkkB7l GRNO7e56IsEw2GvwuNuw4/+UkIiPWH35G67aFLshMnELtaB77FLH0thS/eLZzbva6KuS qt+H5zq5mAWja9In2AzrIM7thnGbfSlbt8ruv4KxrsCuLjqOHjckQ8feBUlK71hG3hb3 cSKQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b="c+Hs/Xbt"; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 83.246.65.91 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=teufel.de Received: from mx-relay05-hz2.antispameurope.com (mx-relay05-hz2.antispameurope.com. [83.246.65.91]) by gmr-mx.google.com with ESMTPS id z4si71184lfr.2.2021.09.02.03.05.10 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 02 Sep 2021 03:05:10 -0700 (PDT) Received-SPF: pass (google.com: domain of sava.jakovljev@teufel.de designates 83.246.65.91 as permitted sender) client-ip=83.246.65.91; Received: from unknown ([212.91.255.190]) by mx-relay05-hz2.antispameurope.com; Thu, 02 Sep 2021 12:05:09 +0200 From: Sava Jakovljev To: CC: Sava Jakovljev Subject: [swupdate] [PATCH] channel_curl: Add ability to define a set of custom HTTP headers Date: Thu, 2 Sep 2021 12:04:44 +0200 Message-ID: <20210902100444.3702590-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-02.teufel.local (10.10.0.81) 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-relay05-hz2.antispameurope.com with 13E2B8C9461 X-cloud-security-connect: unknown[212.91.255.190], TLS=1, IP=212.91.255.190 X-cloud-security-Digest: fd56b0270c6965c261826b0613529c5f X-cloud-security: scantime:1.977 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="c+Hs/Xbt"; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 83.246.65.91 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 +++++--- doc/source/swupdate.rst | 7 +++++-- include/channel_curl.h | 3 ++- suricatta/server_general.c | 2 +- suricatta/server_hawkbit.c | 32 +++++++++++++++++++++++++++++--- suricatta/server_hawkbit.h | 1 + 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/corelib/channel_curl.c b/corelib/channel_curl.c index e910f76..3d7cba5 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->user_headers) { struct dict_entry *entry; char *header; - LIST_FOREACH(entry, channel_data->headers, next) + LIST_FOREACH(entry, channel_data->user_headers, next) { if (ENOMEM_ASPRINTF == asprintf(&header, "%s: %s", diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst index 317c54d..8b4f7af 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,9 @@ Mandatory arguments are marked with '\*': | | | during this period - adapt this value to | | | | your use case! | +-------------------------+----------+--------------------------------------------+ +| -a | strings | Custom HTTP header with given value to be | +| | | send on every HTTP request made. | ++-------------------------+----------+--------------------------------------------+ systemd Integration @@ -706,7 +709,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..4e69eeb 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 *user_headers; + struct dict *received_headers; } channel_data_t; diff --git a/suricatta/server_general.c b/suricatta/server_general.c index 1d11ada..5062745 100644 --- a/suricatta/server_general.c +++ b/suricatta/server_general.c @@ -454,7 +454,7 @@ 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; + channel_data->received_headers = &server_general.httpheaders; result = map_http_retcode(channel->get(channel, (void *)channel_data)); diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c index 33d2eec..62431af 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, + .user_headers = 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,21 @@ 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; + + char *name = NULL; + SETSTRING(name, optarg); + char *value = NULL; + SETSTRING(value, argv[optind++]); + + if (dict_insert_value(&server_hawkbit.httpheaders, + name, + value) < 0) + return SERVER_EINIT; + + break; /* Ignore not recognized options, they can be already parsed by the caller */ case '?': break; @@ -1799,6 +1823,8 @@ server_op_res_t server_start(char *fname, int argc, char *argv[]) return SERVER_EINIT; } + channel_data_defaults.user_headers = &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;