]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: stats: factor the proxy vs scope check into its own function
authorWilly Tarreau <w@1wt.eu>
Fri, 10 Jul 2026 08:45:07 +0000 (10:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 10 Jul 2026 14:27:23 +0000 (16:27 +0200)
We'll need to check for matching between a proxy and a stats scope at
a few more places, so let's first move the code out of its current
function (stats_dump_proxy_to_buffer) into its own function
(stats_proxy_in_scope). At this point it doesn't change anything.
Note that this will have to be backported as this will be used with
a subsequent fix.

include/haproxy/stats-proxy.h
src/stats-proxy.c

index 81a60f0161f4d92d01736750cfa624091fe3a546..06060d7fa758c5412d8fcf37e5d312e2f9a23897 100644 (file)
@@ -6,9 +6,13 @@
 struct buffer;
 struct htx;
 struct stconn;
+struct uri_auth;
+struct proxy;
 
 int stats_dump_proxies(struct stconn *sc, struct buffer *buf, struct htx *htx);
 
 void proxy_stats_clear_counters(int clrall, struct list *stat_modules);
+int stats_proxy_in_scope(const struct proxy *px, const struct uri_auth *uri,
+                         const struct proxy *http_px);
 
 #endif /* _HAPROXY_STATS_PROXY_H */
index a4eda63f6448e81c36701dc289eda833b29fe879..de924bec158b0ad7460be0c0605a59ed71c62bb7 100644 (file)
@@ -1388,6 +1388,41 @@ static int stats_dump_be_line(struct stconn *sc, struct proxy *px)
        return stats_dump_one_line(line, stats_count, appctx);
 }
 
+/* This is used to verify that a given proxy matches one of the scopes defined
+ * by "stats scope" rules. It returns non-zero if the proxy <px> is in any of
+ * the scopes associated with <uri>, or if <uri> doesn't exist or has no scope.
+ * It also accepts the proxy if it matches the requesting one (<http_px>) when
+ * a scope is ".". Otherwise it returns zero indicating that the proxy is out
+ * of scope.
+ */
+int stats_proxy_in_scope(const struct proxy *px, const struct uri_auth *uri,
+                         const struct proxy *http_px)
+{
+       struct stat_scope *scope;
+       int len;
+
+       /* no scope defined ? we're in scope */
+       if (!uri || !uri->scope)
+               return 1;
+
+       /* we have a limited scope, we have to look up the proxy name in all
+        * defined scopes.
+        */
+       len = strlen(px->id);
+       for (scope = uri->scope; scope; scope = scope->next) {
+               /* match exact proxy name */
+               if (scope->px_len == len && memcmp(px->id, scope->px_id, len) == 0)
+                       break;
+
+               /* match '.' which means 'self' proxy */
+               if (px == http_px && strcmp(scope->px_id, ".") == 0)
+                       break;
+       }
+
+       /* scope is non-null if the proxy name was found */
+       return scope != NULL;
+}
+
 /*
  * Dumps statistics for a proxy. The output is sent to the stream connector's
  * input buffer. Returns 0 if it had to stop dumping data because of lack of
@@ -1415,29 +1450,9 @@ more:
        switch (ctx->px_st) {
        case STAT_PX_ST_INIT:
                /* we are on a new proxy */
-               if (uri && uri->scope) {
-                       /* we have a limited scope, we have to check the proxy name */
-                       struct stat_scope *scope;
-                       int len;
-
-                       len = strlen(px->id);
-                       scope = uri->scope;
-
-                       while (scope) {
-                               /* match exact proxy name */
-                               if (scope->px_len == len && !memcmp(px->id, scope->px_id, len))
-                                       break;
-
-                               /* match '.' which means 'self' proxy */
-                               if (strcmp(scope->px_id, ".") == 0 && px == ctx->http_px)
-                                       break;
-                               scope = scope->next;
-                       }
-
-                       /* proxy name not found : don't dump anything */
-                       if (scope == NULL)
-                               return 1;
-               }
+               /* Let's skip it if the proxy is out of scope */
+               if (!stats_proxy_in_scope(px, uri, ctx->http_px))
+                       return 1;
 
                /* if the user has requested a limited output and the proxy
                 * name does not match, skip it.