diff --git a/src/proto_htx.c b/src/proto_htx.c index f229ab3b4..19ab0a370 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -38,6 +38,7 @@ static void htx_end_request(struct stream *s); static void htx_end_response(struct stream *s); static void htx_capture_headers(struct htx *htx, char **cap, struct cap_hdr *cap_hdr); +static int htx_del_hdr_value(char *start, char *end, char **from, char *next); static size_t htx_fmt_req_line(const union h1_sl sl, char *str, size_t len); static void htx_debug_stline(const char *dir, struct stream *s, const union h1_sl sl); static void htx_debug_hdr(const char *dir, struct stream *s, const struct ist n, const struct ist v); @@ -2879,6 +2880,57 @@ static void htx_capture_headers(struct htx *htx, char **cap, struct cap_hdr *cap } } +/* Delete a value in a header between delimiters and . The header + * itself is delimited by and pointers. The number of characters + * displaced is returned, and the pointer to the first delimiter is updated if + * required. The function tries as much as possible to respect the following + * principles : + * - replace delimiter by the one unless points to , + * in which case is simply removed + * - set exactly one space character after the new first delimiter, unless there + * are not enough characters in the block being moved to do so. + * - remove unneeded spaces before the previous delimiter and after the new + * one. + * + * It is the caller's responsibility to ensure that : + * - points to a valid delimiter or ; + * - points to a valid delimiter or ; + * - there are non-space chars before . + */ +static int htx_del_hdr_value(char *start, char *end, char **from, char *next) +{ + char *prev = *from; + + if (prev == start) { + /* We're removing the first value. eat the semicolon, if + * is lower than */ + if (next < end) + next++; + + while (next < end && HTTP_IS_SPHT(*next)) + next++; + } + else { + /* Remove useless spaces before the old delimiter. */ + while (HTTP_IS_SPHT(*(prev-1))) + prev--; + *from = prev; + + /* copy the delimiter and if possible a space if we're + * not at the end of the line. + */ + if (next < end) { + *prev++ = *next++; + if (prev + 1 < next) + *prev++ = ' '; + while (next < end && HTTP_IS_SPHT(*next)) + next++; + } + } + memmove(prev, next, end - next); + return (prev - next); +} + /* Formats the start line of the request (without CRLF) and puts it in and * return the written lenght. The line can be truncated if it exceeds .