include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
-PKG_VERSION:=2.0.9
+PKG_VERSION:=2.0.10
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.haproxy.org/download/2.0/src
-PKG_HASH:=35692801abfd6dde4976cb42fe5cee8aaf61959e743003426073c3141494c589
+PKG_HASH:=1d38ab3dd45e930b209e922a360ee8c636103e21e5b5a2656d3795401316a4ea
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
#!/bin/sh
CLONEURL=https://git.haproxy.org/git/haproxy-2.0.git
-BASE_TAG=v2.0.9
+BASE_TAG=v2.0.10
TMP_REPODIR=tmprepo
PATCHESDIR=patches
--- /dev/null
+commit 54948f3fd310ffc74a6c252dc11046a8a18ab230
+Author: Jerome Magnin <jmagnin@haproxy.com>
+Date: Sat Nov 9 18:00:47 2019 +0100
+
+ BUG/MINOR: stream: init variables when the list is empty
+
+ We need to call vars_init() when the list is empty otherwise we
+ can't use variables in the response scope. This regression was
+ introduced by cda7f3f5 (MINOR: stream: don't prune variables if
+ the list is empty).
+
+ The following config reproduces the issue:
+
+ defaults
+ mode http
+
+ frontend in
+ bind *:11223
+ http-request set-var(req.foo) str("foo") if { path /bar }
+ http-request set-header bar %[var(req.foo)] if { var(req.foo) -m found }
+ http-response set-var(res.bar) str("bar")
+ http-response set-header foo %[var(res.bar)] if { var(res.bar) -m found }
+ use_backend out
+
+ backend out
+ server s1 127.0.0.1:11224
+
+ listen back
+ bind *:11224
+ http-request deny deny_status 200
+
+ > GET /ba HTTP/1.1
+ > Host: localhost:11223
+ > User-Agent: curl/7.66.0
+ > Accept: */*
+ >
+ < HTTP/1.0 200 OK
+ < Cache-Control: no-cache
+ < Content-Type: text/html
+
+ > GET /bar HTTP/1.1
+ > Host: localhost:11223
+ > User-Agent: curl/7.66.0
+ > Accept: */*
+ >
+ < HTTP/1.0 200 OK
+ < Cache-Control: no-cache
+ < Content-Type: text/html
+ < foo: bar
+
+ This must be backported as far as 1.9.
+
+ (cherry picked from commit 2f44e8843a553ef0f9c53c9b27899727de097777)
+ Signed-off-by: Willy Tarreau <w@1wt.eu>
+
+diff --git a/src/stream.c b/src/stream.c
+index 4a7ced22..9fe0efaf 100644
+--- a/src/stream.c
++++ b/src/stream.c
+@@ -2399,10 +2399,9 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
+ if (si_state_in(si_b->state, SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS)) {
+ /* prune the request variables and swap to the response variables. */
+ if (s->vars_reqres.scope != SCOPE_RES) {
+- if (!LIST_ISEMPTY(&s->vars_reqres.head)) {
++ if (!LIST_ISEMPTY(&s->vars_reqres.head))
+ vars_prune(&s->vars_reqres, s->sess, s);
+- vars_init(&s->vars_reqres, SCOPE_RES);
+- }
++ vars_init(&s->vars_reqres, SCOPE_RES);
+ }
+
+ do {
+++ /dev/null
---- a/Makefile
-+++ b/Makefile
-@@ -327,6 +327,15 @@ ifeq ($(TARGET),linux-glibc)
- USE_GETADDRINFO)
- endif
-
-+# For linux >= 2.6.28 and uclibc
-+ifeq ($(TARGET),linux-uclibc)
-+ set_target_defaults = $(call default_opts, \
-+ USE_POLL USE_TPROXY USE_DL USE_RT USE_NETFILTER \
-+ USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_FUTEX USE_LINUX_TPROXY \
-+ USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO \
-+ USE_GETADDRINFO)
-+endif
-+
- # Solaris 8 and above
- ifeq ($(TARGET),solaris)
- # We also enable getaddrinfo() which works since solaris 8.
--- /dev/null
+commit 3a00e5fcc1af121dea16793d47627c16c97fb953
+Author: Christopher Faulet <cfaulet@haproxy.com>
+Date: Wed Nov 27 11:22:37 2019 +0100
+
+ BUG/MINOR: contrib/prometheus-exporter: Use HTX errors and not legacy ones
+
+ This bug was introduced when the commit 32d634f1 ("MINOR:
+ contrib/prometheus-exporter: filter exported metrics by scope") was backported
+ to 2.0.
+
+ In 2.0, Error chunks exist in raw format (http_err_chunks[]) and in HTX format
+ (htx_err_chunks[]). Prometheus exported only supports the HTX. So error must not
+ be reported using the raw chunks.
+
+ This fix is specific to 2.0. No backport needed.
+
+diff --git a/contrib/prometheus-exporter/service-prometheus.c b/contrib/prometheus-exporter/service-prometheus.c
+index 56d49a39..cfbfb8c3 100644
+--- a/contrib/prometheus-exporter/service-prometheus.c
++++ b/contrib/prometheus-exporter/service-prometheus.c
+@@ -2292,7 +2292,7 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+ return 1;
+
+ error:
+- err = &http_err_chunks[HTTP_ERR_400];
++ err = &htx_err_chunks[HTTP_ERR_400];
+ channel_erase(res);
+ res->buf.data = b_data(err);
+ memcpy(res->buf.area, b_head(err), b_data(err));
+++ /dev/null
---- a/include/common/openssl-compat.h
-+++ b/include/common/openssl-compat.h
-@@ -217,7 +217,8 @@ static inline int EVP_PKEY_base_id(EVP_PKEY *pkey)
- #define TLSEXT_signature_ecdsa 3
- #endif
-
--#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER < 0x20700000L)
-+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x20700000L))
- #define X509_getm_notBefore X509_get_notBefore
- #define X509_getm_notAfter X509_get_notAfter
- #endif
--- /dev/null
+commit 200c6215fe9c592d576f52d4a79627381ed6aa7f
+Author: William Dauchy <w.dauchy@criteo.com>
+Date: Tue Nov 26 12:56:26 2019 +0100
+
+ BUG/MINOR: contrib/prometheus-exporter: decode parameter and value only
+
+ we were decoding all substring and then parsing; this could lead to
+ consider & and = in decoding result as delimiters where it should not.
+ this patch reverses the order by first parsing and then decoding each key
+ and value separately.
+
+ we also stop parsing after number sign (#).
+
+ This patch should be backported to 2.1 and 2.0
+
+ Signed-off-by: William Dauchy <w.dauchy@criteo.com>
+ (cherry picked from commit c65f656d75091db3087a752dbc956159392fc8f2)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+ (cherry picked from commit 8ec21c5fef89f13fea2ac9be55d55215d4b9104a)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+
+diff --git a/contrib/prometheus-exporter/service-prometheus.c b/contrib/prometheus-exporter/service-prometheus.c
+index cfbfb8c3..c34ee0e1 100644
+--- a/contrib/prometheus-exporter/service-prometheus.c
++++ b/contrib/prometheus-exporter/service-prometheus.c
+@@ -2220,7 +2220,8 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+ struct channel *res = si_ic(si);
+ struct htx *req_htx, *res_htx;
+ struct htx_sl *sl;
+- const char *p, *end;
++ char *p, *key, *value;
++ const char *end;
+ struct buffer *err;
+ int default_scopes = PROMEX_FL_SCOPE_ALL;
+ int len;
+@@ -2234,57 +2235,72 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+ if (!p)
+ goto end;
+ end = HTX_SL_REQ_UPTR(sl) + HTX_SL_REQ_ULEN(sl);
+- len = end-p;
+
+- /* Decode the query-string */
++ /* copy the query-string */
++ len = end - p;
+ chunk_reset(&trash);
+ memcpy(trash.area, p, len);
+ trash.area[len] = 0;
+- len = url_decode(trash.area);
+- if (len == -1)
+- goto error;
+ p = trash.area;
+- end = p + len;
++ end = trash.area + len;
+
+ /* Parse the query-string */
+- while (p < end) {
+- if (*p == '&')
++ while (p < end && *p && *p != '#') {
++ value = NULL;
++
++ /* decode parameter name */
++ key = p;
++ while (p < end && *p != '=' && *p != '&' && *p != '#')
+ ++p;
+- else if (*p == 's' && (end-p) >= 6 && !memcmp(p, "scope=", 6)) {
+- default_scopes = 0; /* at least a scope defined, unset default scopes */
+- p += 6; /* now p point on the parameter value */
+- len = 0; /* len is the value length */
+- while ((p+len) < end && *(p+len) != '&')
+- ++len;
++ /* found a value */
++ if (*p == '=') {
++ *(p++) = 0;
++ value = p;
++ }
++ else if (*p == '&')
++ *(p++) = 0;
++ else if (*p == '#')
++ *p = 0;
++ len = url_decode(key);
++ if (len == -1)
++ goto error;
++
++ /* decode value */
++ if (value) {
++ while (p < end && *p != '=' && *p != '&' && *p != '#')
++ ++p;
++ if (*p == '=')
++ goto error;
++ if (*p == '&')
++ *(p++) = 0;
++ else if (*p == '#')
++ *p = 0;
++ len = url_decode(value);
++ if (len == -1)
++ goto error;
++ }
+
+- if (len == 0)
++ if (!strcmp(key, "scope")) {
++ default_scopes = 0; /* at least a scope defined, unset default scopes */
++ if (!value)
++ goto error;
++ else if (*value == 0)
+ appctx->ctx.stats.flags &= ~PROMEX_FL_SCOPE_ALL;
+- else if (len == 1 && *p == '*')
++ else if (*value == '*')
+ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_ALL;
+- else if (len == 6) {
+- if (!memcmp(p, "global", len))
+- appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
+- else if (!memcmp(p, "server", len))
+- appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
+- }
+- else if (len == 7 && !memcmp(p, "backend", len))
++ else if (!strcmp(value, "global"))
++ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
++ else if (!strcmp(value, "server"))
++ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
++ else if (!strcmp(value, "backend"))
+ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_BACK;
+- else if (len == 8 && !memcmp(p, "frontend", len))
++ else if (!strcmp(value, "frontend"))
+ appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_FRONT;
+ else
+ goto error;
+-
+- p += len;
+ }
+- else if (*p == 'n' && (end-p) >= 8 && !memcmp(p, "no-maint", 8)) {
++ else if (!strcmp(key, "no-maint"))
+ appctx->ctx.stats.flags |= PROMEX_FL_NO_MAINT_SRV;
+- p += 8;
+- }
+- else {
+- /* ignore all other params for now */
+- while (p < end && *p != '&')
+- p++;
+- }
+ }
+
+ end:
--- /dev/null
+--- a/Makefile
++++ b/Makefile
+@@ -327,6 +327,15 @@ ifeq ($(TARGET),linux-glibc)
+ USE_GETADDRINFO)
+ endif
+
++# For linux >= 2.6.28 and uclibc
++ifeq ($(TARGET),linux-uclibc)
++ set_target_defaults = $(call default_opts, \
++ USE_POLL USE_TPROXY USE_DL USE_RT USE_NETFILTER \
++ USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_FUTEX USE_LINUX_TPROXY \
++ USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO \
++ USE_GETADDRINFO)
++endif
++
+ # Solaris 8 and above
+ ifeq ($(TARGET),solaris)
+ # We also enable getaddrinfo() which works since solaris 8.
--- /dev/null
+--- a/include/common/openssl-compat.h
++++ b/include/common/openssl-compat.h
+@@ -217,7 +217,8 @@ static inline int EVP_PKEY_base_id(EVP_PKEY *pkey)
+ #define TLSEXT_signature_ecdsa 3
+ #endif
+
+-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER < 0x20700000L)
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
++ (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x20700000L))
+ #define X509_getm_notBefore X509_get_notBefore
+ #define X509_getm_notAfter X509_get_notAfter
+ #endif