|
|
- 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:
|