]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ha-inject: Move some mux h1 parsing functions to cfgparse-mux_h1.c 20251209-ha-inject
authorFrederic Lecaille <flecaille@haproxy.com>
Wed, 10 Dec 2025 17:37:01 +0000 (18:37 +0100)
committerFrederic Lecaille <flecaille@haproxy.com>
Wed, 10 Dec 2025 17:37:01 +0000 (18:37 +0100)
Add cfgparse-mux_h1.c new C file to avoid compiling such code for ha-inject.
Move mux_h1.c parsing functions to this new file.

Makefile
include/haproxy/mux_h1-t.h
src/cfgparse-mux_h1.c [new file with mode: 0644]
src/mux_h1.c

index 63cf006da921ad435a4e6ebc228cec830d9687e1..c38198b5862f19f9ca879f4e60e1caaa64dc49fd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1005,7 +1005,8 @@ OBJS_COMMON += src/mux_h2.o src/mux_h1.o src/mux_fcgi.o \
         src/version.o src/ncbmbuf.o src/ech.o \
 
 OBJS += $(OBJS_COMMON) src/acl.o src/cfgdiag.o src/cfgparse.o \
-        src/cfgparse-global.o src/cfgparse-listen.o src/cfgparse-mux_h2.o \
+        src/cfgparse-global.o src/cfgparse-listen.o src/cfgparse-mux_h1.o \
+        src/cfgparse-mux_h2.o \
         src/cfgparse-tcp.o src/cfgparse-thread.o \
         src/cfgparse-unix.o src/check.o src/dns.o src/dns_ring.o src/event_hdl.o \
         src/extcheck.o src/filters.o src/flt_bwlim.o src/flt_http_comp.o \
index a886d364c4bd9766844f1a7c5819b06fbf8586d5..18a0701cd8aa698d1ad15c7c752d8cf01817b08d 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef _HAPROXY_MUX_H1_T_H
 #define _HAPROXY_MUX_H1_T_H
 
+#include <import/ist.h>
+
 #include <haproxy/api-t.h>
 #include <haproxy/show_flags-t.h>
 
@@ -112,6 +114,21 @@ static forceinline char *h1c_show_flags(char *buf, size_t len, const char *delim
 #define H1S_F_BODYLESS_REQ   0x00040000 /* Bodyless request message */
 #define H1S_F_BODYLESS_RESP  0x00080000 /* Bodyless response message */
 
+/* An entry in a headers map */
+struct h1_hdr_entry  {
+       struct ist name;
+       struct ebpt_node node;
+};
+
+/* Map of headers used to convert outgoing headers */
+struct h1_hdrs_map {
+       char *name;
+       struct eb_root map;
+};
+
+extern struct h1_hdrs_map hdrs_map;
+extern int accept_payload_with_any_method;
+
 /* This function is used to report flags in debugging tools. Please reflect
  * below any single-bit flag addition above in the same order via the
  * __APPEND_FLAG macro. The new end of the buffer is returned.
diff --git a/src/cfgparse-mux_h1.c b/src/cfgparse-mux_h1.c
new file mode 100644 (file)
index 0000000..0db05ea
--- /dev/null
@@ -0,0 +1,254 @@
+#include <string.h>
+
+#include <import/ebistree.h>
+
+#include <haproxy/api.h>
+#include <haproxy/cfgparse.h>
+#include <haproxy/errors.h>
+#include <haproxy/mux_h1-t.h>
+#include <haproxy/tools.h>
+
+/* Add an entry in the headers map. Returns -1 on error and 0 on success. */
+static int add_hdr_case_adjust(const char *from, const char *to, char **err)
+{
+       struct h1_hdr_entry *entry;
+
+       /* Be sure there is a non-empty <to> */
+       if (!strlen(to)) {
+               memprintf(err, "expect <to>");
+               return -1;
+       }
+
+       /* Be sure only the case differs between <from> and <to> */
+       if (strcasecmp(from, to) != 0) {
+               memprintf(err, "<from> and <to> must not differ except the case");
+               return -1;
+       }
+
+       /* Be sure <from> does not already existsin the tree */
+       if (ebis_lookup(&hdrs_map.map, from)) {
+               memprintf(err, "duplicate entry '%s'", from);
+               return -1;
+       }
+
+       /* Create the entry and insert it in the tree */
+       entry = malloc(sizeof(*entry));
+       if (!entry) {
+               memprintf(err, "out of memory");
+               return -1;
+       }
+
+       entry->node.key = strdup(from);
+       entry->name = ist(strdup(to));
+       if (!entry->node.key || !isttest(entry->name)) {
+               free(entry->node.key);
+               istfree(&entry->name);
+               free(entry);
+               memprintf(err, "out of memory");
+               return -1;
+       }
+       ebis_insert(&hdrs_map.map, &entry->node);
+       return 0;
+}
+
+static void h1_hdeaders_case_adjust_deinit()
+{
+       struct ebpt_node *node, *next;
+       struct h1_hdr_entry *entry;
+
+       node = ebpt_first(&hdrs_map.map);
+       while (node) {
+               next = ebpt_next(node);
+               ebpt_delete(node);
+               entry = container_of(node, struct h1_hdr_entry, node);
+               free(entry->node.key);
+               istfree(&entry->name);
+               free(entry);
+               node = next;
+       }
+       free(hdrs_map.name);
+}
+
+static int cfg_h1_headers_case_adjust_postparser()
+{
+       FILE *file = NULL;
+       char *c, *key_beg, *key_end, *value_beg, *value_end;
+       char *err;
+       int rc, line = 0, err_code = 0;
+
+       if (!hdrs_map.name)
+               goto end;
+
+       file = fopen(hdrs_map.name, "r");
+       if (!file) {
+               ha_alert("h1-headers-case-adjust-file '%s': failed to open file.\n",
+                        hdrs_map.name);
+                err_code |= ERR_ALERT | ERR_FATAL;
+               goto end;
+       }
+
+       /* now parse all lines. The file may contain only two header name per
+        * line, separated by spaces. All heading and trailing spaces will be
+        * ignored. Lines starting with a # are ignored.
+        */
+       while (fgets(trash.area, trash.size, file) != NULL) {
+               line++;
+               c = trash.area;
+
+               /* strip leading spaces and tabs */
+               while (*c == ' ' || *c == '\t')
+                       c++;
+
+               /* ignore emptu lines, or lines beginning with a dash */
+               if (*c == '#' || *c == '\0' || *c == '\r' || *c == '\n')
+                       continue;
+
+               /* look for the end of the key */
+               key_beg = c;
+               while (*c != '\0' && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
+                       c++;
+               key_end = c;
+
+               /* strip middle spaces and tabs */
+               while (*c == ' ' || *c == '\t')
+                       c++;
+
+               /* look for the end of the value, it is the end of the line */
+               value_beg = c;
+               while (*c && *c != '\n' && *c != '\r')
+                       c++;
+               value_end = c;
+
+               /* trim possibly trailing spaces and tabs */
+               while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
+                       value_end--;
+
+               /* set final \0 and check entries */
+               *key_end = '\0';
+               *value_end = '\0';
+
+               err = NULL;
+               rc = add_hdr_case_adjust(key_beg, value_beg, &err);
+               if (rc < 0) {
+                       ha_alert("h1-headers-case-adjust-file '%s' : %s at line %d.\n",
+                                hdrs_map.name, err, line);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       free(err);
+                       goto end;
+               }
+               if (rc > 0) {
+                       ha_warning("h1-headers-case-adjust-file '%s' : %s at line %d.\n",
+                                  hdrs_map.name, err, line);
+                       err_code |= ERR_WARN;
+                       free(err);
+               }
+       }
+
+  end:
+       if (file)
+               fclose(file);
+       hap_register_post_deinit(h1_hdeaders_case_adjust_deinit);
+       return err_code;
+}
+
+/* config parser for global "h1-accept-payload_=-with-any-method" */
+static int cfg_parse_h1_accept_payload_with_any_method(char **args, int section_type, struct proxy *curpx,
+                                                      const struct proxy *defpx, const char *file, int line,
+                                                      char **err)
+{
+       if (too_many_args(0, args, err, NULL))
+               return -1;
+
+       accept_payload_with_any_method = 1;
+       return 0;
+}
+
+
+/* config parser for global "h1-header-case-adjust" */
+static int cfg_parse_h1_header_case_adjust(char **args, int section_type, struct proxy *curpx,
+                                          const struct proxy *defpx, const char *file, int line,
+                                          char **err)
+{
+        if (too_many_args(2, args, err, NULL))
+                return -1;
+        if (!*(args[1]) || !*(args[2])) {
+                memprintf(err, "'%s' expects <from> and <to> as argument.", args[0]);
+               return -1;
+       }
+       return add_hdr_case_adjust(args[1], args[2], err);
+}
+
+/* config parser for global "h1-headers-case-adjust-file" */
+static int cfg_parse_h1_headers_case_adjust_file(char **args, int section_type, struct proxy *curpx,
+                                                const struct proxy *defpx, const char *file, int line,
+                                                char **err)
+{
+        if (too_many_args(1, args, err, NULL))
+                return -1;
+        if (!*(args[1])) {
+                memprintf(err, "'%s' expects <file> as argument.", args[0]);
+               return -1;
+       }
+       free(hdrs_map.name);
+       hdrs_map.name = strdup(args[1]);
+       if  (!hdrs_map.name) {
+               memprintf(err, "'%s %s' : out of memory", args[0], args[1]);
+               return -1;
+       }
+       return 0;
+}
+
+/* config parser for global "tune.h1.zero-copy-fwd-recv" */
+static int cfg_parse_h1_zero_copy_fwd_rcv(char **args, int section_type, struct proxy *curpx,
+                                          const struct proxy *defpx, const char *file, int line,
+                                          char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (strcmp(args[1], "on") == 0)
+               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_RCV;
+       else if (strcmp(args[1], "off") == 0)
+               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_RCV;
+       else {
+               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
+               return -1;
+       }
+       return 0;
+}
+
+/* config parser for global "tune.h1.zero-copy-fwd-send" */
+static int cfg_parse_h1_zero_copy_fwd_snd(char **args, int section_type, struct proxy *curpx,
+                                         const struct proxy *defpx, const char *file, int line,
+                                         char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (strcmp(args[1], "on") == 0)
+               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_SND;
+       else if (strcmp(args[1], "off") == 0)
+               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_SND;
+       else {
+               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
+               return -1;
+       }
+       return 0;
+}
+
+/* config keyword parsers */
+static struct cfg_kw_list cfg_kws = {{ }, {
+               { CFG_GLOBAL, "h1-accept-payload-with-any-method", cfg_parse_h1_accept_payload_with_any_method },
+               { CFG_GLOBAL, "h1-case-adjust", cfg_parse_h1_header_case_adjust },
+               { CFG_GLOBAL, "h1-case-adjust-file", cfg_parse_h1_headers_case_adjust_file },
+               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-recv", cfg_parse_h1_zero_copy_fwd_rcv },
+               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-send", cfg_parse_h1_zero_copy_fwd_snd },
+               { 0, NULL, NULL },
+       }
+};
+
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
+REGISTER_CONFIG_POSTPARSER("h1-headers-map", cfg_h1_headers_case_adjust_postparser);
+
+
+
index 7b9cddf8d58bbe9eadeabb0074330c7746d5219d..3cdb6ad10da62d09a4fa0445e306776782ad80f3 100644 (file)
@@ -79,21 +79,9 @@ struct h1s {
        char ws_key[25];       /* websocket handshake key */
 };
 
-/* Map of headers used to convert outgoing headers */
-struct h1_hdrs_map {
-       char *name;
-       struct eb_root map;
-};
-
-/* An entry in a headers map */
-struct h1_hdr_entry  {
-       struct ist name;
-       struct ebpt_node node;
-};
-
 /* Declare the headers map */
-static struct h1_hdrs_map hdrs_map = { .name = NULL, .map  = EB_ROOT };
-static int accept_payload_with_any_method = 0;
+struct h1_hdrs_map hdrs_map = { .name = NULL, .map  = EB_ROOT };
+int accept_payload_with_any_method = 0;
 
 /* trace source and events */
 static void h1_trace(enum trace_level level, uint64_t mask,
@@ -5589,49 +5577,6 @@ static int h1_show_sd(struct buffer *msg, struct sedesc *sd, const char *pfx)
 }
 
 
-/* Add an entry in the headers map. Returns -1 on error and 0 on success. */
-static int add_hdr_case_adjust(const char *from, const char *to, char **err)
-{
-       struct h1_hdr_entry *entry;
-
-       /* Be sure there is a non-empty <to> */
-       if (!strlen(to)) {
-               memprintf(err, "expect <to>");
-               return -1;
-       }
-
-       /* Be sure only the case differs between <from> and <to> */
-       if (strcasecmp(from, to) != 0) {
-               memprintf(err, "<from> and <to> must not differ except the case");
-               return -1;
-       }
-
-       /* Be sure <from> does not already existsin the tree */
-       if (ebis_lookup(&hdrs_map.map, from)) {
-               memprintf(err, "duplicate entry '%s'", from);
-               return -1;
-       }
-
-       /* Create the entry and insert it in the tree */
-       entry = malloc(sizeof(*entry));
-       if (!entry) {
-               memprintf(err, "out of memory");
-               return -1;
-       }
-
-       entry->node.key = strdup(from);
-       entry->name = ist(strdup(to));
-       if (!entry->node.key || !isttest(entry->name)) {
-               free(entry->node.key);
-               istfree(&entry->name);
-               free(entry);
-               memprintf(err, "out of memory");
-               return -1;
-       }
-       ebis_insert(&hdrs_map.map, &entry->node);
-       return 0;
-}
-
 /* Migrate the the connection to the current thread.
  * Return 0 if successful, non-zero otherwise.
  * Expected to be called with the old thread lock held.
@@ -5724,206 +5669,6 @@ static int h1_takeover(struct connection *conn, int orig_tid, int release)
        return -1;
 }
 
-
-static void h1_hdeaders_case_adjust_deinit()
-{
-       struct ebpt_node *node, *next;
-       struct h1_hdr_entry *entry;
-
-       node = ebpt_first(&hdrs_map.map);
-       while (node) {
-               next = ebpt_next(node);
-               ebpt_delete(node);
-               entry = container_of(node, struct h1_hdr_entry, node);
-               free(entry->node.key);
-               istfree(&entry->name);
-               free(entry);
-               node = next;
-       }
-       free(hdrs_map.name);
-}
-
-static int cfg_h1_headers_case_adjust_postparser()
-{
-       FILE *file = NULL;
-       char *c, *key_beg, *key_end, *value_beg, *value_end;
-       char *err;
-       int rc, line = 0, err_code = 0;
-
-       if (!hdrs_map.name)
-               goto end;
-
-       file = fopen(hdrs_map.name, "r");
-       if (!file) {
-               ha_alert("h1-headers-case-adjust-file '%s': failed to open file.\n",
-                        hdrs_map.name);
-                err_code |= ERR_ALERT | ERR_FATAL;
-               goto end;
-       }
-
-       /* now parse all lines. The file may contain only two header name per
-        * line, separated by spaces. All heading and trailing spaces will be
-        * ignored. Lines starting with a # are ignored.
-        */
-       while (fgets(trash.area, trash.size, file) != NULL) {
-               line++;
-               c = trash.area;
-
-               /* strip leading spaces and tabs */
-               while (*c == ' ' || *c == '\t')
-                       c++;
-
-               /* ignore emptu lines, or lines beginning with a dash */
-               if (*c == '#' || *c == '\0' || *c == '\r' || *c == '\n')
-                       continue;
-
-               /* look for the end of the key */
-               key_beg = c;
-               while (*c != '\0' && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
-                       c++;
-               key_end = c;
-
-               /* strip middle spaces and tabs */
-               while (*c == ' ' || *c == '\t')
-                       c++;
-
-               /* look for the end of the value, it is the end of the line */
-               value_beg = c;
-               while (*c && *c != '\n' && *c != '\r')
-                       c++;
-               value_end = c;
-
-               /* trim possibly trailing spaces and tabs */
-               while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
-                       value_end--;
-
-               /* set final \0 and check entries */
-               *key_end = '\0';
-               *value_end = '\0';
-
-               err = NULL;
-               rc = add_hdr_case_adjust(key_beg, value_beg, &err);
-               if (rc < 0) {
-                       ha_alert("h1-headers-case-adjust-file '%s' : %s at line %d.\n",
-                                hdrs_map.name, err, line);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       free(err);
-                       goto end;
-               }
-               if (rc > 0) {
-                       ha_warning("h1-headers-case-adjust-file '%s' : %s at line %d.\n",
-                                  hdrs_map.name, err, line);
-                       err_code |= ERR_WARN;
-                       free(err);
-               }
-       }
-
-  end:
-       if (file)
-               fclose(file);
-       hap_register_post_deinit(h1_hdeaders_case_adjust_deinit);
-       return err_code;
-}
-
-/* config parser for global "h1-accept-payload_=-with-any-method" */
-static int cfg_parse_h1_accept_payload_with_any_method(char **args, int section_type, struct proxy *curpx,
-                                                      const struct proxy *defpx, const char *file, int line,
-                                                      char **err)
-{
-        if (too_many_args(0, args, err, NULL))
-                return -1;
-       accept_payload_with_any_method = 1;
-       return 0;
-}
-
-
-/* config parser for global "h1-header-case-adjust" */
-static int cfg_parse_h1_header_case_adjust(char **args, int section_type, struct proxy *curpx,
-                                          const struct proxy *defpx, const char *file, int line,
-                                          char **err)
-{
-        if (too_many_args(2, args, err, NULL))
-                return -1;
-        if (!*(args[1]) || !*(args[2])) {
-                memprintf(err, "'%s' expects <from> and <to> as argument.", args[0]);
-               return -1;
-       }
-       return add_hdr_case_adjust(args[1], args[2], err);
-}
-
-/* config parser for global "h1-headers-case-adjust-file" */
-static int cfg_parse_h1_headers_case_adjust_file(char **args, int section_type, struct proxy *curpx,
-                                                const struct proxy *defpx, const char *file, int line,
-                                                char **err)
-{
-        if (too_many_args(1, args, err, NULL))
-                return -1;
-        if (!*(args[1])) {
-                memprintf(err, "'%s' expects <file> as argument.", args[0]);
-               return -1;
-       }
-       free(hdrs_map.name);
-       hdrs_map.name = strdup(args[1]);
-       if  (!hdrs_map.name) {
-               memprintf(err, "'%s %s' : out of memory", args[0], args[1]);
-               return -1;
-       }
-       return 0;
-}
-
-/* config parser for global "tune.h1.zero-copy-fwd-recv" */
-static int cfg_parse_h1_zero_copy_fwd_rcv(char **args, int section_type, struct proxy *curpx,
-                                          const struct proxy *defpx, const char *file, int line,
-                                          char **err)
-{
-       if (too_many_args(1, args, err, NULL))
-               return -1;
-
-       if (strcmp(args[1], "on") == 0)
-               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_RCV;
-       else if (strcmp(args[1], "off") == 0)
-               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_RCV;
-       else {
-               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
-               return -1;
-       }
-       return 0;
-}
-
-/* config parser for global "tune.h1.zero-copy-fwd-send" */
-static int cfg_parse_h1_zero_copy_fwd_snd(char **args, int section_type, struct proxy *curpx,
-                                         const struct proxy *defpx, const char *file, int line,
-                                         char **err)
-{
-       if (too_many_args(1, args, err, NULL))
-               return -1;
-
-       if (strcmp(args[1], "on") == 0)
-               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_SND;
-       else if (strcmp(args[1], "off") == 0)
-               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_SND;
-       else {
-               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
-               return -1;
-       }
-       return 0;
-}
-
-/* config keyword parsers */
-static struct cfg_kw_list cfg_kws = {{ }, {
-               { CFG_GLOBAL, "h1-accept-payload-with-any-method", cfg_parse_h1_accept_payload_with_any_method },
-               { CFG_GLOBAL, "h1-case-adjust", cfg_parse_h1_header_case_adjust },
-               { CFG_GLOBAL, "h1-case-adjust-file", cfg_parse_h1_headers_case_adjust_file },
-               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-recv", cfg_parse_h1_zero_copy_fwd_rcv },
-               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-send", cfg_parse_h1_zero_copy_fwd_snd },
-               { 0, NULL, NULL },
-       }
-};
-
-INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
-REGISTER_CONFIG_POSTPARSER("h1-headers-map", cfg_h1_headers_case_adjust_postparser);
-
-
 /****************************************/
 /* MUX initialization and instantiation */
 /****************************************/