Browse Source

Merge pull request #9367 from gladiac1337/haproxy-2.0.1-master

haproxy: Update HAProxy to v2.0.1
lilik-openwrt-22.03
Rosen Penev 6 years ago
committed by GitHub
parent
commit
c319b9f53d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 277 additions and 686 deletions
  1. +4
    -4
      net/haproxy/Makefile
  2. +1
    -1
      net/haproxy/get-latest-patches.sh
  3. +0
    -32
      net/haproxy/patches/000-BUG-MEDIUM-h2-htx-Update-data-length-of-the-HTX-when-the-cookie-list-is-built.patch
  4. +81
    -0
      net/haproxy/patches/000-BUG-MINOR-mworker-cli-dont-output-a-n-before-the-response.patch
  5. +30
    -0
      net/haproxy/patches/001-BUG-MEDIUM-ssl-Dont-attempt-to-set-alpn-if-were-not-using-SSL.patch
  6. +0
    -32
      net/haproxy/patches/001-BUG-MINOR-lua-htx-Make-txn-req_req_-and-txn-res_rep_-HTX-aware.patch
  7. +35
    -0
      net/haproxy/patches/002-BUG-MEDIUM-mux-h1-Always-release-H1C-if-a-shutdown-for-writes-was-reported.patch
  8. +0
    -29
      net/haproxy/patches/002-BUG-MINOR-mux-h1-Add-the-header-connection-in-lower-case-in-outgoing-messages.patch
  9. +51
    -0
      net/haproxy/patches/003-BUG-MEDIUM-checks-unblock-signals-in-external-checks.patch
  10. +0
    -253
      net/haproxy/patches/003-BUG-MEDIUM-compression-Set-Vary-Accept-Encoding-for-compressed-responses.patch
  11. +48
    -0
      net/haproxy/patches/004-BUG-MINOR-mux-h1-Skip-trailers-for-non-chunked-outgoing-messages.patch
  12. +0
    -66
      net/haproxy/patches/004-MINOR-htx-Add-the-function-htx_change_blk_value_len.patch
  13. +0
    -133
      net/haproxy/patches/005-BUG-MEDIUM-htx-Fully-update-HTX-message-when-the-block-value-is-changed.patch
  14. +27
    -0
      net/haproxy/patches/005-BUG-MINOR-mux-h1-Dont-return-the-empty-chunk-on-HEAD-responses.patch
  15. +0
    -27
      net/haproxy/patches/006-BUG-MEDIUM-mux-h2-Reset-padlen-when-several-frames-are-demux.patch
  16. +0
    -0
      net/haproxy/patches/006-OPENWRT-add-uclibc-support.patch
  17. +0
    -30
      net/haproxy/patches/007-BUG-MEDIUM-mux-h2-Remove-the-padding-length-when-a-DATA-frame-size-is-checked.patch
  18. +0
    -0
      net/haproxy/patches/007-OPENWRT-openssl-deprecated.patch
  19. +0
    -39
      net/haproxy/patches/008-BUG-MEDIUM-lb_fwlc-Dont-test-the-servers-lb_tree-from-outside-the-lock.patch
  20. +0
    -40
      net/haproxy/patches/009-BUG-MAJOR-sample-Wrong-stick-table-name-parsing-in-if-unless-ACL-condition.patch

+ 4
- 4
net/haproxy/Makefile View File

@ -10,12 +10,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
PKG_VERSION:=2.0.0
PKG_RELEASE:=3
PKG_VERSION:=2.0.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.haproxy.org/download/2.0/src
PKG_HASH:=fe0a0d69e1091066a91b8d39199c19af8748e0e872961c6fc43c91ec7a28ff20
PKG_HASH:=9975c475ba6f19aac4b665d8705f7b9f7911df7fc316ba7b9efd6fe263181eb1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
@ -56,7 +56,7 @@ define Package/haproxy/Default/description
endef
define Package/haproxy
DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +libncursesw +libreadline +libatomic
DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +libncurses +libreadline +libatomic
TITLE+= (with SSL support)
VARIANT:=ssl
$(call Package/haproxy/Default)


+ 1
- 1
net/haproxy/get-latest-patches.sh View File

@ -1,7 +1,7 @@
#!/bin/bash
CLONEURL=http://git.haproxy.org/git/haproxy-2.0.git
BASE_TAG=v2.0.0
BASE_TAG=v2.0.1
TMP_REPODIR=tmprepo
PATCHESDIR=patches


+ 0
- 32
net/haproxy/patches/000-BUG-MEDIUM-h2-htx-Update-data-length-of-the-HTX-when-the-cookie-list-is-built.patch View File

@ -1,32 +0,0 @@
commit 032cff38c24d8359dc575423a94d19b6ad8bf848
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Mon Jun 17 11:44:47 2019 +0200
BUG/MEDIUM: h2/htx: Update data length of the HTX when the cookie list is built
When an H2 request is converted into an HTX message, All cookie headers are
grouped into one, each value separated by a semicolon (;). To do so, we add the
header "cookie" with the first value and then we update the value by appending
other cookies. But during this operation, only the size of the HTX block is
updated. And not the data length of the whole HTX message.
It is an old bug and it seems to work by chance till now. But it may lead to
undefined behaviour by time to time.
This patch must be backported to 2.0 and 1.9
(cherry picked from commit 0c6de00d7c842a682bba7586ef34fb10f69ec63c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/h2.c b/src/h2.c
index 9681aca5..32c1ef16 100644
--- a/src/h2.c
+++ b/src/h2.c
@@ -737,6 +737,7 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
goto fail;
htx_set_blk_value_len(blk, tl);
+ htx->data += vl+2;
*(char *)(htx_get_blk_ptr(htx, blk) + bs + 0) = ';';
*(char *)(htx_get_blk_ptr(htx, blk) + bs + 1) = ' ';
memcpy(htx_get_blk_ptr(htx, blk) + bs + 2, list[ck].v.ptr, vl);

+ 81
- 0
net/haproxy/patches/000-BUG-MINOR-mworker-cli-dont-output-a-n-before-the-response.patch View File

@ -0,0 +1,81 @@
commit 1bd140ea3fab97ccd37adf9d0c106d52af9e53fa
Author: William Lallemand <wlallemand@haproxy.com>
Date: Mon Jul 1 10:56:15 2019 +0200
BUG/MINOR: mworker/cli: don't output a \n before the response
When using a level lower than admin on the master CLI, a \n is output
before the response, this is caused by the response of the "operator" or
"user" that are sent before the actual command.
To fix this problem we introduce the flag APPCTX_CLI_ST1_NOLF which ask
a command response to not be followed by the final \n.
This patch made a special case with the command operator and user
followed by a - so they are not followed by \n.
This patch must be backported to 2.0 and 1.9.
(cherry picked from commit ad03288e6b28d816abb443cf8c6d984a72bb91a6)
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
diff --git a/include/types/applet.h b/include/types/applet.h
index c9e02d17..1f3a4983 100644
--- a/include/types/applet.h
+++ b/include/types/applet.h
@@ -50,6 +50,7 @@ struct applet {
#define APPCTX_CLI_ST1_PROMPT (1 << 0)
#define APPCTX_CLI_ST1_PAYLOAD (1 << 1)
+#define APPCTX_CLI_ST1_NOLF (1 << 2)
/* Context of a running applet. */
struct appctx {
diff --git a/src/cli.c b/src/cli.c
index 44ddc7bf..9a9f80f9 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -821,7 +821,7 @@ static void cli_io_handler(struct appctx *appctx)
prompt = "\n> ";
}
else {
- if (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD))
+ if (!(appctx->st1 & (APPCTX_CLI_ST1_PAYLOAD|APPCTX_CLI_ST1_NOLF)))
prompt = "\n";
}
@@ -848,6 +848,8 @@ static void cli_io_handler(struct appctx *appctx)
/* switch state back to GETREQ to read next requests */
appctx->st0 = CLI_ST_GETREQ;
+ /* reactivate the \n at the end of the response for the next command */
+ appctx->st1 &= ~APPCTX_CLI_ST1_NOLF;
}
}
@@ -1442,6 +1444,10 @@ static int cli_parse_show_lvl(char **args, char *payload, struct appctx *appctx,
/* parse and set the CLI level dynamically */
static int cli_parse_set_lvl(char **args, char *payload, struct appctx *appctx, void *private)
{
+ /* this will ask the applet to not output a \n after the command */
+ if (!strcmp(args[1], "-"))
+ appctx->st1 |= APPCTX_CLI_ST1_NOLF;
+
if (!strcmp(args[0], "operator")) {
if (!cli_has_level(appctx, ACCESS_LVL_OPER)) {
return 1;
@@ -2097,11 +2103,11 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
if (pcli_has_level(s, ACCESS_LVL_ADMIN)) {
goto end;
} else if (pcli_has_level(s, ACCESS_LVL_OPER)) {
- ci_insert_line2(req, 0, "operator", strlen("operator"));
- ret += strlen("operator") + 2;
+ ci_insert_line2(req, 0, "operator -", strlen("operator -"));
+ ret += strlen("operator -") + 2;
} else if (pcli_has_level(s, ACCESS_LVL_USER)) {
- ci_insert_line2(req, 0, "user", strlen("user"));
- ret += strlen("user") + 2;
+ ci_insert_line2(req, 0, "user -", strlen("user -"));
+ ret += strlen("user -") + 2;
}
}
end:

+ 30
- 0
net/haproxy/patches/001-BUG-MEDIUM-ssl-Dont-attempt-to-set-alpn-if-were-not-using-SSL.patch View File

@ -0,0 +1,30 @@
commit aa2ecea6f711f50192476b26a5b1d767108bd761
Author: Olivier Houchard <ohouchard@haproxy.com>
Date: Fri Jun 28 14:10:33 2019 +0200
BUG/MEDIUM: ssl: Don't attempt to set alpn if we're not using SSL.
Checks use ssl_sock_set_alpn() to set the ALPN if check-alpn is used, however
check-alpn failed to check if the connection was indeed using SSL, and thus,
would crash if check-alpn was used on a non-SSL connection. Fix this by
making sure the connection uses SSL before attempting to set the ALPN.
This should be backported to 2.0 and 1.9.
(cherry picked from commit e488ea865a433d93efcb14c0c602918070c6b208)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 05240063..c9fffbec 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6411,6 +6411,9 @@ void ssl_sock_set_alpn(struct connection *conn, const unsigned char *alpn, int l
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ if (!ssl_sock_is_ssl(conn))
+ return;
+
SSL_set_alpn_protos(ctx->ssl, alpn, len);
#endif
}

+ 0
- 32
net/haproxy/patches/001-BUG-MINOR-lua-htx-Make-txn-req_req_-and-txn-res_rep_-HTX-aware.patch View File

@ -1,32 +0,0 @@
commit 5a8549e68225070d0b79cbbb9c5f791e103685e7
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Mon Jun 17 13:36:06 2019 +0200
BUG/MINOR: lua/htx: Make txn.req_req_* and txn.res_rep_* HTX aware
These bindings were not updated to support HTX streams.
This patch must be backported to 2.0 and 1.9. It fixes the issue #124.
(cherry picked from commit ea418748dd22331e9798cfd8f5e25b436cd577e3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/hlua.c b/src/hlua.c
index 28abd083..32f0e8db 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -5375,7 +5375,13 @@ __LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
if (!(re = regex_comp(reg, 1, 1, NULL)))
WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
- http_transform_header_str(htxn->s, msg, name, name_len, value, re, action);
+ if (IS_HTX_STRM(htxn->s)) {
+ struct htx *htx = htxbuf(&msg->chn->buf);
+
+ htx_transform_header_str(htxn->s, msg->chn, htx, ist2(name, name_len), value, re, action);
+ }
+ else
+ http_transform_header_str(htxn->s, msg, name, name_len, value, re, action);
regex_free(re);
return 0;
}

+ 35
- 0
net/haproxy/patches/002-BUG-MEDIUM-mux-h1-Always-release-H1C-if-a-shutdown-for-writes-was-reported.patch View File

@ -0,0 +1,35 @@
commit 9fa93f6220a374f724491fd781d44d31f307671f
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Fri Jun 28 17:41:42 2019 +0200
BUG/MEDIUM: mux-h1: Always release H1C if a shutdown for writes was reported
We must take care of this when the stream is detached from the
connection. Otherwise, on the server side, the connexion is inserted in the list
of idle connections of the session. But when reused, because the shutdown for
writes was already catched, nothing is sent to the server and the session is
blocked with a freezed connection.
This patch must be backported to 2.0 and 1.9. It is related to the issue #136
reported on Github.
(cherry picked from commit 3ac0f43020e1cd77198020201e4e482a1c2ef8ac)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 3d2bd8b8..e497e6f6 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -2192,9 +2192,9 @@ static void h1_detach(struct conn_stream *cs)
}
}
- /* We don't want to close right now unless the connection is in error */
- if ((h1c->flags & (H1C_F_CS_ERROR|H1C_F_CS_SHUTDOWN|H1C_F_UPG_H2C)) ||
- (h1c->conn->flags & CO_FL_ERROR) || !h1c->conn->owner)
+ /* We don't want to close right now unless the connection is in error or shut down for writes */
+ if ((h1c->flags & (H1C_F_CS_ERROR|H1C_F_CS_SHUTW_NOW|H1C_F_CS_SHUTDOWN|H1C_F_UPG_H2C)) ||
+ (h1c->conn->flags & (CO_FL_ERROR|CO_FL_SOCK_WR_SH)) || !h1c->conn->owner)
h1_release(h1c);
else {
tasklet_wakeup(h1c->wait_event.tasklet);

+ 0
- 29
net/haproxy/patches/002-BUG-MINOR-mux-h1-Add-the-header-connection-in-lower-case-in-outgoing-messages.patch View File

@ -1,29 +0,0 @@
commit 661bfc3d0e1b7756db59d00d86e316f694cae3c6
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Mon Jun 17 14:07:46 2019 +0200
BUG/MINOR: mux-h1: Add the header connection in lower case in outgoing messages
When necessary, this header is directly added in outgoing messages by the H1
multiplexer. Because there is no HTX conversion first, the header name is not
converserted to its lower case version. So, it must be added in lower case by
the multiplexer.
This patch must be backported to 2.0 and 1.9.
(cherry picked from commit a110ecbd843e156dd01c6ac581c735be5e240d5b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 317f1a55..21deb354 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -1642,7 +1642,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
/* There is no "Connection:" header and
* it the conn_mode must be
* processed. So do it */
- n = ist("Connection");
+ n = ist("connection");
v = ist("");
h1_process_output_conn_mode(h1s, h1m, &v);
if (v.len) {

+ 51
- 0
net/haproxy/patches/003-BUG-MEDIUM-checks-unblock-signals-in-external-checks.patch View File

@ -0,0 +1,51 @@
commit afc313e6cd4be32f3c3d212e875d4dbcef8a0c70
Author: Willy Tarreau <w@1wt.eu>
Date: Mon Jul 1 07:51:29 2019 +0200
BUG/MEDIUM: checks: unblock signals in external checks
As discussed in issue #140, processes are forked with signals blocked
resulting in haproxy's kill being ignored. This happens when the command
takes more time to complete than the configured check timeout or interval.
Just calling "sleep 30" every second makes the problem obvious.
The fix simply consists in unblocking the signals in the child after the
fork. It needs to be backported to all stable branches containing external
checks and where signals are blocked on startup. It's unclear when it
started, but the following config exhibits the issue :
global
external-check
listen www
bind :8001
timeout client 5s
timeout server 5s
timeout connect 5s
option external-check
external-check command "$PWD/sleep10.sh"
server local 127.0.0.1:80 check inter 200
$ cat sleep10.sh
#!/bin/sh
exec /bin/sleep 10
The "sleep" processes keep accumulating for 10 seconds and stabilize
around 25 when the bug is present. Just issuing "killall sleep" has no
effect on them, and stopping haproxy leaves these processes behind.
(cherry picked from commit 2df8cad0fea2d1a4ca8dd58f384df3c3c3f5d7ee)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/checks.c b/src/checks.c
index c175a752..e31eb173 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1997,6 +1997,7 @@ static int connect_proc_chk(struct task *t)
environ = check->envp;
extchk_setenv(check, EXTCHK_HAPROXY_SERVER_CURCONN, ultoa_r(s->cur_sess, buf, sizeof(buf)));
+ haproxy_unblock_signals();
execvp(px->check_command, check->argv);
ha_alert("Failed to exec process for external health check: %s. Aborting.\n",
strerror(errno));

+ 0
- 253
net/haproxy/patches/003-BUG-MEDIUM-compression-Set-Vary-Accept-Encoding-for-compressed-responses.patch View File

@ -1,253 +0,0 @@
commit eaf650083924a697cde3379703984c5e7a5ebd41
Author: Tim Duesterhus <tim@bastelstu.be>
Date: Mon Jun 17 16:10:07 2019 +0200
BUG/MEDIUM: compression: Set Vary: Accept-Encoding for compressed responses
Make HAProxy set the `Vary: Accept-Encoding` response header if it compressed
the server response.
Technically the `Vary` header SHOULD also be set for responses that would
normally be compressed based off the current configuration, but are not due
to a missing or invalid `Accept-Encoding` request header or due to the
maximum compression rate being exceeded.
Not setting the header in these cases does no real harm, though: An
uncompressed response might be returned by a Cache, even if a compressed
one could be retrieved from HAProxy. This increases the traffic to the end
user if the cache is unable to compress itself, but it saves another
roundtrip to HAProxy.
see the discussion on the mailing list: https://www.mail-archive.com/haproxy@formilux.org/msg34221.html
Message-ID: 20190617121708.GA2964@1wt.eu
A small issue remains: The User-Agent is not added to the `Vary` header,
despite being relevant to the response. Adding the User-Agent header would
make responses effectively uncacheable and it's unlikely to see a Mozilla/4
in the wild in 2019.
Add a reg-test to ensure the behaviour as described in this commit message.
see issue #121
Should be backported to all branches with compression (i.e. 1.6+).
(cherry picked from commit 721d686bd10dc6993859f9026ad907753d1d2064)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/reg-tests/compression/vary.vtc b/reg-tests/compression/vary.vtc
new file mode 100644
index 00000000..0a060e4b
--- /dev/null
+++ b/reg-tests/compression/vary.vtc
@@ -0,0 +1,187 @@
+varnishtest "Compression sets Vary header"
+
+#REQUIRE_VERSION=1.9
+#REQUIRE_OPTION=ZLIB|SLZ
+
+feature ignore_unknown_macro
+
+server s1 {
+ rxreq
+ expect req.url == "/plain/accept-encoding-gzip"
+ expect req.http.accept-encoding == "gzip"
+ txresp \
+ -hdr "Content-Type: text/plain" \
+ -bodylen 100
+
+ rxreq
+ expect req.url == "/plain/accept-encoding-invalid"
+ expect req.http.accept-encoding == "invalid"
+ txresp \
+ -hdr "Content-Type: text/plain" \
+ -bodylen 100
+
+ rxreq
+ expect req.url == "/plain/accept-encoding-null"
+ expect req.http.accept-encoding == "<undef>"
+ txresp \
+ -hdr "Content-Type: text/plain" \
+ -bodylen 100
+
+ rxreq
+ expect req.url == "/html/accept-encoding-gzip"
+ expect req.http.accept-encoding == "gzip"
+ txresp \
+ -hdr "Content-Type: text/html" \
+ -bodylen 100
+
+ rxreq
+ expect req.url == "/html/accept-encoding-invalid"
+ expect req.http.accept-encoding == "invalid"
+ txresp \
+ -hdr "Content-Type: text/html" \
+ -bodylen 100
+
+
+ rxreq
+ expect req.url == "/html/accept-encoding-null"
+ expect req.http.accept-encoding == "<undef>"
+ txresp \
+ -hdr "Content-Type: text/html" \
+ -bodylen 100
+
+ rxreq
+ expect req.url == "/dup-etag/accept-encoding-gzip"
+ expect req.http.accept-encoding == "gzip"
+ txresp \
+ -hdr "Content-Type: text/plain" \
+ -hdr "ETag: \"123\"" \
+ -hdr "ETag: \"123\"" \
+ -bodylen 100
+} -repeat 2 -start
+
+
+haproxy h1 -conf {
+ defaults
+ mode http
+ ${no-htx} option http-use-htx
+ timeout connect 1s
+ timeout client 1s
+ timeout server 1s
+
+ frontend fe-gzip
+ bind "fd@${fe_gzip}"
+ default_backend be-gzip
+
+ backend be-gzip
+ compression algo gzip
+ compression type text/plain
+ server www ${s1_addr}:${s1_port}
+
+ frontend fe-nothing
+ bind "fd@${fe_nothing}"
+ default_backend be-nothing
+
+ backend be-nothing
+ server www ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_fe_gzip_sock} {
+ txreq -url "/plain/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.content-encoding == "gzip"
+ expect resp.http.vary == "Accept-Encoding"
+ gunzip
+ expect resp.bodylen == 100
+
+ txreq -url "/plain/accept-encoding-invalid" \
+ -hdr "Accept-Encoding: invalid"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/plain/accept-encoding-null"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-invalid" \
+ -hdr "Accept-Encoding: invalid"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-null"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/dup-etag/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+} -run
+
+# This Client duplicates c1, against the "nothing" frontend, ensuring no Vary header is ever set.
+client c2 -connect ${h1_fe_nothing_sock} {
+ txreq -url "/plain/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/plain/accept-encoding-invalid" \
+ -hdr "Accept-Encoding: invalid"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/plain/accept-encoding-null"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-invalid" \
+ -hdr "Accept-Encoding: invalid"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/html/accept-encoding-null"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+
+ txreq -url "/dup-etag/accept-encoding-gzip" \
+ -hdr "Accept-Encoding: gzip"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.vary == "<undef>"
+ expect resp.bodylen == 100
+} -run
diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c
index b04dcd14..37f237fe 100644
--- a/src/flt_http_comp.c
+++ b/src/flt_http_comp.c
@@ -523,6 +523,9 @@ http_set_comp_reshdr(struct comp_state *st, struct stream *s, struct http_msg *m
}
}
+ if (http_header_add_tail2(msg, &txn->hdr_idx, "Vary: Accept-Encoding", 21) < 0)
+ goto error;
+
return 1;
error:
@@ -577,6 +580,9 @@ htx_set_comp_reshdr(struct comp_state *st, struct stream *s, struct http_msg *ms
}
}
+ if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding")))
+ goto error;
+
return 1;
error:

+ 48
- 0
net/haproxy/patches/004-BUG-MINOR-mux-h1-Skip-trailers-for-non-chunked-outgoing-messages.patch View File

@ -0,0 +1,48 @@
commit 52131680c42ddbfa6f2b5d109ffc79c28f44e42a
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Thu Jun 27 17:40:14 2019 +0200
BUG/MINOR: mux-h1: Skip trailers for non-chunked outgoing messages
Unlike H1, H2 messages may contains trailers while the header "Content-Length"
is set. Indeed, because of the framed structure of HTTP/2, it is no longer
necessary to use the chunked transfer encoding. So Trailing HEADERS frames,
after all DATA frames, may be added on messages with an explicit content length.
But in H1, it is impossible to have trailers on non-chunked messages. So when
outgoing messages are formatted by the H1 multiplexer, if the message is not
chunked, all trailers must be dropped.
This patch must be backported to 2.0 and 1.9. However, the patch will have to be
adapted for the 1.9.
(cherry picked from commit 5433a0b0215c791b4165bddd360a254fa141c6e9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h1.c b/src/mux_h1.c
index e497e6f6..e7d769b4 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -1696,7 +1696,9 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
goto done;
}
else if (type == HTX_BLK_EOT || type == HTX_BLK_TLR) {
- if (!chunk_memcat(&tmp, "0\r\n", 3))
+ /* If the message is not chunked, never
+ * add the last chunk. */
+ if ((h1m->flags & H1_MF_CHNK) && !chunk_memcat(&tmp, "0\r\n", 3))
goto copy;
goto trailers;
}
@@ -1715,6 +1717,11 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
goto error;
trailers:
h1m->state = H1_MSG_TRAILERS;
+ /* If the message is not chunked, ignore
+ * trailers. It may happen with H2 messages. */
+ if (!(h1m->flags & H1_MF_CHNK))
+ break;
+
if (type == HTX_BLK_EOT) {
if (!chunk_memcat(&tmp, "\r\n", 2))
goto copy;

+ 0
- 66
net/haproxy/patches/004-MINOR-htx-Add-the-function-htx_change_blk_value_len.patch View File

@ -1,66 +0,0 @@
commit 8d09dc21dc913d1540d07d1019a51c430317eae1
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Tue Jun 18 09:37:00 2019 +0200
MINOR: htx: Add the function htx_change_blk_value_len()
As its name suggest, this function change the value length of a block. But it
also update the HTX message accordingly. It simplifies the HTX API. The function
htx_set_blk_value_len() is still available and must be used with caution because
this one does not update the HTX message. It just updates the HTX block. It
should be considered as an internal function. When possible,
htx_change_blk_value_len() should be used instead.
This function is used to fix a bug affecting the 2.0. So, this patch must be
backported to 2.0.
(cherry picked from commit bb0efcdd293de33607a6eba075971b49857375e2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/include/common/htx.h b/include/common/htx.h
index 9631c618..7d15365a 100644
--- a/include/common/htx.h
+++ b/include/common/htx.h
@@ -470,7 +470,41 @@ static inline struct htx_blk *htx_get_next_blk(const struct htx *htx,
}
/* Changes the size of the value. It is the caller responsibility to change the
- * value itself, make sure there is enough space and update allocated value.
+ * value itself, make sure there is enough space and update allocated
+ * value. This function updates the HTX message accordingly.
+ */
+static inline void htx_change_blk_value_len(struct htx *htx, struct htx_blk *blk, uint32_t newlen)
+{
+ enum htx_blk_type type = htx_get_blk_type(blk);
+ uint32_t oldlen, sz;
+ int32_t delta;
+
+ sz = htx_get_blksz(blk);
+ switch (type) {
+ case HTX_BLK_HDR:
+ case HTX_BLK_TLR:
+ oldlen = (blk->info >> 8) & 0xfffff;
+ blk->info = (type << 28) + (newlen << 8) + (blk->info & 0xff);
+ break;
+ default:
+ oldlen = blk->info & 0xfffffff;
+ blk->info = (type << 28) + newlen;
+ break;
+ }
+
+ /* Update HTTP message */
+ delta = (newlen - oldlen);
+ htx->data += delta;
+ if (blk->addr+sz == htx->tail_addr)
+ htx->tail_addr += delta;
+ else if (blk->addr+sz == htx->head_addr)
+ htx->head_addr += delta;
+}
+
+/* Changes the size of the value. It is the caller responsibility to change the
+ * value itself, make sure there is enough space and update allocated
+ * value. Unlike the function htx_change_blk_value_len(), this one does not
+ * update the HTX message. So it should be used with caution.
*/
static inline void htx_set_blk_value_len(struct htx_blk *blk, uint32_t vlen)
{

+ 0
- 133
net/haproxy/patches/005-BUG-MEDIUM-htx-Fully-update-HTX-message-when-the-block-value-is-changed.patch View File

@ -1,133 +0,0 @@
commit 41dc8432f87622145390dc1b1467a5ee14ba184c
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Tue Jun 18 09:49:16 2019 +0200
BUG/MEDIUM: htx: Fully update HTX message when the block value is changed
Everywhere the value length of a block is changed, calling the function
htx_set_blk_value_len(), the HTX message must be updated. But at many places,
because of the recent changes in the HTX structure, this update was only
partially done. tail_addr and head_addr values were not systematically updated.
In fact, the function htx_set_blk_value_len() was designed as an internal
function to the HTX API. And we used it from outside by convenience. But it is
really painfull and error prone to let the caller update the HTX message. So
now, we use the function htx_change_blk_value_len() wherever is possible. It
changes the value length of a block and updates the HTX message accordingly.
This patch must be backported to 2.0.
(cherry picked from commit 3e2638ee04407a1d9e9376f0c518f67fca7deaa4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/h2.c b/src/h2.c
index 32c1ef16..990d602b 100644
--- a/src/h2.c
+++ b/src/h2.c
@@ -736,8 +736,7 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
if (tl > fs)
goto fail;
- htx_set_blk_value_len(blk, tl);
- htx->data += vl+2;
+ htx_change_blk_value_len(htx, blk, tl);
*(char *)(htx_get_blk_ptr(htx, blk) + bs + 0) = ';';
*(char *)(htx_get_blk_ptr(htx, blk) + bs + 1) = ' ';
memcpy(htx_get_blk_ptr(htx, blk) + bs + 2, list[ck].v.ptr, vl);
diff --git a/src/http_htx.c b/src/http_htx.c
index 7322b337..bc26e5ba 100644
--- a/src/http_htx.c
+++ b/src/http_htx.c
@@ -461,10 +461,7 @@ int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx)
}
/* Update the block content and its len */
memmove(start, start+len, v.len-len);
- htx_set_blk_value_len(blk, v.len-len);
-
- /* Update HTX msg */
- htx->data -= len;
+ htx_change_blk_value_len(htx, blk, v.len-len);
/* Finally update the ctx */
ctx->value.ptr = start;
diff --git a/src/htx.c b/src/htx.c
index bfd136f4..81492598 100644
--- a/src/htx.c
+++ b/src/htx.c
@@ -406,15 +406,8 @@ void htx_truncate(struct htx *htx, uint32_t offset)
offset -= sz;
continue;
}
- if (type == HTX_BLK_DATA) {
- htx_set_blk_value_len(blk, offset);
- htx->data -= (sz - offset);
-
- if (blk->addr+sz == htx->tail_addr)
- htx->tail_addr -= offset;
- else if (blk->addr+sz == htx->head_addr)
- htx->head_addr -= offset;
- }
+ if (type == HTX_BLK_DATA)
+ htx_change_blk_value_len(htx, blk, offset);
offset = 0;
}
while (blk)
@@ -522,14 +515,7 @@ struct htx_blk *htx_add_data_atonce(struct htx *htx, struct ist data)
/* Append data and update the block itself */
ptr = htx_get_blk_ptr(htx, tailblk);
memcpy(ptr+sz, data.ptr, len);
- htx_set_blk_value_len(tailblk, sz+len);
-
- /* Update HTTP message */
- htx->data += len;
- if (tailblk->addr+sz == htx->tail_addr)
- htx->tail_addr += len;
- else if (tailblk->addr+sz == htx->head_addr)
- htx->head_addr += len;
+ htx_change_blk_value_len(htx, tailblk, sz+len);
if (data.len == len) {
blk = tailblk;
@@ -988,14 +974,7 @@ size_t htx_add_data(struct htx *htx, const struct ist data)
/* Append data and update the block itself */
ptr = htx_get_blk_ptr(htx, tailblk);
memcpy(ptr + sz, data.ptr, len);
- htx_set_blk_value_len(tailblk, sz + len);
-
- /* Update HTTP message */
- htx->data += len;
- if (tailblk->addr+sz == htx->tail_addr)
- htx->tail_addr += len;
- else if (tailblk->addr+sz == htx->head_addr)
- htx->head_addr += len;
+ htx_change_blk_value_len(htx, tailblk, sz+len);
BUG_ON((int32_t)htx->tail_addr < 0);
BUG_ON((int32_t)htx->head_addr < 0);
diff --git a/src/proto_htx.c b/src/proto_htx.c
index 7f501366..d821e38c 100644
--- a/src/proto_htx.c
+++ b/src/proto_htx.c
@@ -4314,10 +4314,8 @@ static void htx_manage_client_side_cookies(struct stream *s, struct channel *req
hdr_end = (preserve_hdr ? del_from : hdr_beg);
}
if ((hdr_end - hdr_beg) != ctx.value.len) {
- if (hdr_beg != hdr_end) {
- htx_set_blk_value_len(ctx.blk, hdr_end - hdr_beg);
- htx->data -= ctx.value.len - (hdr_end - hdr_beg);
- }
+ if (hdr_beg != hdr_end)
+ htx_change_blk_value_len(htx, ctx.blk, hdr_end - hdr_beg);
else
http_remove_header(htx, &ctx);
}
@@ -4495,8 +4493,7 @@ static void htx_manage_server_side_cookies(struct stream *s, struct channel *res
next += stripped_before;
hdr_end += stripped_before;
- htx_set_blk_value_len(ctx.blk, hdr_end - hdr_beg);
- htx->data -= ctx.value.len - (hdr_end - hdr_beg);
+ htx_change_blk_value_len(htx, ctx.blk, hdr_end - hdr_beg);
ctx.value.len = hdr_end - hdr_beg;
}

+ 27
- 0
net/haproxy/patches/005-BUG-MINOR-mux-h1-Dont-return-the-empty-chunk-on-HEAD-responses.patch View File

@ -0,0 +1,27 @@
commit 33d58b51e0f1bf68603aa86c9125ae75d6964454
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Mon Jul 1 16:17:30 2019 +0200
BUG/MINOR: mux-h1: Don't return the empty chunk on HEAD responses
HEAD responses must not have any body payload. But, because of a bug, for chunk
reponses, the empty chunk was always added.
This patch fixes the Github issue #146. It must be backported to 2.0 and 1.9.
(cherry picked from commit b8fc304e8f996f0d9835e4d6524ef8961d3be076)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h1.c b/src/mux_h1.c
index e7d769b4..37cc8252 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -1682,6 +1682,8 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
h1m->flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
h1s->flags &= ~H1S_F_HAVE_O_CONN;
}
+ else if ((h1m->flags & H1_MF_RESP) && h1s->meth == HTTP_METH_HEAD)
+ h1m->state = H1_MSG_DONE;
else
h1m->state = H1_MSG_DATA;
break;

+ 0
- 27
net/haproxy/patches/006-BUG-MEDIUM-mux-h2-Reset-padlen-when-several-frames-are-demux.patch View File

@ -1,27 +0,0 @@
commit 3d574a587dc3704e93bcd29b16d54d96069667b4
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Tue Jun 18 12:22:38 2019 +0200
BUG/MEDIUM: mux-h2: Reset padlen when several frames are demux
In the function h2_process_demux(), if several frames are parsed, the padding
length must be reset between each frame. Otherwise we may wrongly think a frame
has a padding block because the previous one was padded.
This patch must be backported to 2.0 and 1.9.
(cherry picked from commit dd2a5620d594523cd515a629e105a9a2b64345bb)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h2.c b/src/mux_h2.c
index d02168df..c06d5d68 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -2316,6 +2316,7 @@ static void h2_process_demux(struct h2c *h2c)
break;
}
+ padlen = 0;
if (h2_ft_bit(hdr.ft) & H2_FT_PADDED_MASK && hdr.ff & H2_F_PADDED) {
/* If the frame is padded (HEADERS, PUSH_PROMISE or DATA),
* we read the pad length and drop it from the remaining

net/haproxy/patches/010-add-uclibc-support.patch → net/haproxy/patches/006-OPENWRT-add-uclibc-support.patch View File


+ 0
- 30
net/haproxy/patches/007-BUG-MEDIUM-mux-h2-Remove-the-padding-length-when-a-DATA-frame-size-is-checked.patch View File

@ -1,30 +0,0 @@
commit 4fb65f421b4d650711e5d8b9dbcbf4bf589d26cc
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Wed Jun 19 09:25:58 2019 +0200
BUG/MEDIUM: mux-h2: Remove the padding length when a DATA frame size is checked
When a DATA frame is processed for a message with a content-length, we first
take care to not have a frame size that exceeds the remaining to
read. Otherwise, an error is triggered. But we must remove the padding length
from the frame size because the padding is not included in the announced
content-length.
This patch must be backported to 2.0 and 1.9.
(cherry picked from commit 4f09ec812adbd9336cddc054660a7fb5cd54b459)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h2.c b/src/mux_h2.c
index c06d5d68..5bb85181 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -2177,7 +2177,7 @@ static int h2c_frt_handle_data(struct h2c *h2c, struct h2s *h2s)
goto strm_err;
}
- if ((h2s->flags & H2_SF_DATA_CLEN) && h2c->dfl > h2s->body_len) {
+ if ((h2s->flags & H2_SF_DATA_CLEN) && (h2c->dfl - h2c->dpl) > h2s->body_len) {
/* RFC7540#8.1.2 */
error = H2_ERR_PROTOCOL_ERROR;
goto strm_err;

net/haproxy/patches/020-openssl-deprecated.patch → net/haproxy/patches/007-OPENWRT-openssl-deprecated.patch View File


+ 0
- 39
net/haproxy/patches/008-BUG-MEDIUM-lb_fwlc-Dont-test-the-servers-lb_tree-from-outside-the-lock.patch View File

@ -1,39 +0,0 @@
commit 3f0b1de623d09f8668db34c1be696f7245de7d50
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Wed Jun 19 10:50:38 2019 +0200
BUG/MEDIUM: lb_fwlc: Don't test the server's lb_tree from outside the lock
In the function fwlc_srv_reposition(), the server's lb_tree is tested from
outside the lock. So it is possible to remove it after the test and then call
eb32_insert() in fwlc_queue_srv() with a NULL root pointer, which is
invalid. Moving the test in the scope of the lock fixes the bug.
This issue was reported on Github, issue #126.
This patch must be backported to 2.0, 1.9 and 1.8.
(cherry picked from commit 1ae2a8878170ded922f2c4d32b6704af7689bbfd)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/lb_fwlc.c b/src/lb_fwlc.c
index 174dc67e..5fa81739 100644
--- a/src/lb_fwlc.c
+++ b/src/lb_fwlc.c
@@ -66,12 +66,11 @@ static inline void fwlc_queue_srv(struct server *s)
*/
static void fwlc_srv_reposition(struct server *s)
{
- if (!s->lb_tree)
- return;
-
HA_SPIN_LOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
- fwlc_dequeue_srv(s);
- fwlc_queue_srv(s);
+ if (s->lb_tree) {
+ fwlc_dequeue_srv(s);
+ fwlc_queue_srv(s);
+ }
HA_SPIN_UNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
}

+ 0
- 40
net/haproxy/patches/009-BUG-MAJOR-sample-Wrong-stick-table-name-parsing-in-if-unless-ACL-condition.patch View File

@ -1,40 +0,0 @@
commit 9eae8935663bc0b27c23018e8cc24ae9a3e31732
Author: Frédéric Lécaille <flecaille@haproxy.com>
Date: Thu Jun 20 09:31:04 2019 +0200
BUG/MAJOR: sample: Wrong stick-table name parsing in "if/unless" ACL condition.
This bug was introduced by 1b8e68e commit which supposed the stick-table was always
stored in struct arg at parsing time. This is never the case with the usage of
"if/unless" conditions in stick-table declared as backends. In this case, this is
the name of the proxy which must be considered as the stick-table name.
This must be backported to 2.0.
(cherry picked from commit 9417f4534ad742eda35c4cc3d1ccb390f75ea4b1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/sample.c b/src/sample.c
index 67f59e84..77ec9b1e 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1245,15 +1245,11 @@ int smp_resolve_args(struct proxy *p)
break;
case ARGT_TAB:
- if (!arg->data.str.data) {
- ha_alert("parsing [%s:%d] : missing table name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
- cur->file, cur->line,
- cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
- cfgerr++;
- continue;
- }
+ if (arg->data.str.data)
+ stktname = arg->data.str.area;
+ else
+ stktname = px->id;
- stktname = arg->data.str.area;
t = stktable_find_by_name(stktname);
if (!t) {
ha_alert("parsing [%s:%d] : unable to find table '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",

Loading…
Cancel
Save