]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
report: add option to inject additional HTTP headers
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 1 Apr 2026 05:32:46 +0000 (07:32 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 16 Apr 2026 19:12:20 +0000 (21:12 +0200)
This is useful when debugging things. The option is named and implements
the same logic as imdsd.

src/imds/imdsd.c
src/report/report-upload.c
src/report/report.c
src/report/report.h
src/shared/web-util.c
src/shared/web-util.h

index 2b7bf113353cfbea875894885193415e90639c69..5ed7d1df338b73690eeb6a2b86b29bfb6f4620ac 100644 (file)
@@ -2243,10 +2243,6 @@ static bool http_header_name_valid(const char *a) {
         return a && ascii_is_valid(a) && !string_has_cc(a, /* ok= */ NULL) && !strchr(a, ':');
 }
 
-static bool http_header_valid(const char *a) {
-        return a && ascii_is_valid(a) && !string_has_cc(a, /* ok= */ NULL) && strchr(a, ':');
-}
-
 static int parse_argv(int argc, char *argv[]) {
         int r;
 
index 897d7d1159f911e58228e6c7f5e9a36ba31e3c73..3022bd30493874bc97a480aa179e029d2b2fc736 100644 (file)
@@ -97,6 +97,10 @@ int upload_collected(Context *context) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create curl header: %m");
 
+        r = curl_append_to_header(&header, arg_extra_headers);
+        if (r < 0)
+                return log_error_errno(r, "Failed to create curl header: %m");
+
         _cleanup_(curl_easy_cleanupp) CURL *curl = curl_easy_init();
         if (!curl)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOSR),
index b02a48b28b46a246539e51ada1966313edabdf7d..c45c4da7ea63e7928682b575c8c73d6ebd4dd8c2 100644 (file)
@@ -26,6 +26,7 @@
 #include "time-util.h"
 #include "varlink-idl-util.h"
 #include "verbs.h"
+#include "web-util.h"
 
 #define METRICS_OR_FACTS_MAX 4096U
 #define METRICS_OR_FACTS_LINKS_MAX 128U
@@ -40,6 +41,7 @@ char *arg_url = NULL;
 char *arg_key = NULL;
 char *arg_cert = NULL;
 char *arg_trust = NULL;
+char **arg_extra_headers = NULL;
 usec_t arg_network_timeout_usec = TIMEOUT_USEC;
 
 STATIC_DESTRUCTOR_REGISTER(arg_matches, strv_freep);
@@ -47,6 +49,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_url, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_key, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_cert, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_trust, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_extra_headers, strv_freep);
 
 typedef struct LinkInfo {
         Context *context;
@@ -1052,9 +1055,23 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
                         if (r < 0)
                                 return log_error_errno(r, "Failed to parse --network-timeout value: %s", arg);
                         break;
+
+                OPTION_LONG("extra-header", "NAME: VALUE",
+                            "Inject additional header into the upload request"):
+                        if (isempty(arg)) {
+                                arg_extra_headers = strv_free(arg_extra_headers);
+                                break;
+                        }
+
+                        if (!http_header_valid(arg))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid HTTP header: %s", arg);
+
+                        if (strv_extend(&arg_extra_headers, arg) < 0)
+                                return log_oom();
+                        break;
                 }
 
-        if ((arg_url || arg_key || arg_cert || arg_trust) && !HAVE_LIBCURL)
+        if ((arg_url || arg_key || arg_cert || arg_trust || arg_extra_headers) && !HAVE_LIBCURL)
                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Compiled without libcurl.");
 
         *ret_args = option_parser_get_args(&state);
index 69c9c5851b7a332f6362783a9774fdff82ada1a8..4d7b5bdd3f0bba3f51646fc18115fffb17275116 100644 (file)
@@ -10,6 +10,7 @@
 #define REPORT_TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
 
 extern char *arg_url, *arg_key, *arg_cert, *arg_trust;
+extern char **arg_extra_headers;
 extern usec_t arg_network_timeout_usec;
 
 typedef enum Action {
index 23f3004700b462bd9a95a7c7074ad5ea9d192c08..bfcea982a9dfc0bd2acb19f0a759c2e0f2d0b125 100644 (file)
@@ -50,6 +50,13 @@ bool documentation_url_is_valid(const char *url) {
         return ascii_is_valid(p);
 }
 
+bool http_header_valid(const char *header) {
+        return header &&
+                ascii_is_valid(header) &&
+                !string_has_cc(header, /* ok= */ NULL) &&
+                strchr(header, ':');
+}
+
 bool http_etag_is_valid(const char *etag) {
         if (isempty(etag))
                 return false;
index 8a2f5c537bcef417e6b85a3440076ffb099d3e08..ec154c107aebcd690f0a024018737efb6bc9e4fa 100644 (file)
@@ -6,4 +6,5 @@
 bool http_url_is_valid(const char *url) _pure_;
 bool file_url_is_valid(const char *url) _pure_;
 bool documentation_url_is_valid(const char *url) _pure_;
+bool http_header_valid(const char *header) _pure_;
 bool http_etag_is_valid(const char *etag) _pure_;