This is an automated email from the ASF dual-hosted git repository.

chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new 9291db9d Render vars builtin as an HTML name-value table (#3413)
9291db9d is described below

commit 9291db9d6d2ad19ead25ef09f4f3702b22e68c25
Author: darion-yaphet <[email protected]>
AuthorDate: Thu Sep 3 14:10:35 2026 +0800

    Render vars builtin as an HTML name-value table (#3413)
    
    * fix(vars): render /vars as an HTML name-value table
    
    Replace the plain paragraph list with a gridtable so variable
    names and values align in columns, and keep expandable flot
    charts in a dedicated detail row.
    
    * test(vars): prevent HTML table rendering regressions
    
    Cover HTML responses triggered by a User-Agent, including the grid table, 
variable row, and expandable detail row. Preserve plain-text output coverage.
    
    Constraint: HTML mode is selected by the User-Agent header
    Confidence: high
    Scope-risk: narrow
    Reversibility: clean
    Directive: Update both rendering-mode assertions when changing VarsService 
markup
    Tested: BuiltinServiceTest.vars
    Not-tested: Full suite; the default C++0x test configuration is 
incompatible with local GoogleTest 1.17
---
 src/brpc/builtin/vars_service.cpp      | 37 +++++++++++++++++++++++-----------
 test/brpc_builtin_service_unittest.cpp | 24 +++++++++++++++++++---
 2 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/src/brpc/builtin/vars_service.cpp 
b/src/brpc/builtin/vars_service.cpp
index 007b0404..473b370e 100644
--- a/src/brpc/builtin/vars_service.cpp
+++ b/src/brpc/builtin/vars_service.cpp
@@ -45,6 +45,7 @@ namespace brpc {
 void PutVarsHeading(std::ostream& os, bool expand_all) {
     os << "<script language=\"javascript\" type=\"text/javascript\" 
src=\"/js/jquery_min\"></script>\n"
         "<script language=\"javascript\" type=\"text/javascript\" 
src=\"/js/flot_min\"></script>\n"
+       << gridtable_style()
        << TabsHead()
        << "<style type=\"text/css\">\n"
         "#layer1 { margin:0; padding:0; width:1111px; }\n"
@@ -66,6 +67,9 @@ void PutVarsHeading(std::ostream& os, bool expand_all) {
         "}\n"
         // style of <p>
         "p {padding: 2px 0; margin: 0px; }\n"
+        ".detail-row td {\n"
+        "  padding:0px;\n"
+        "}\n"
         // style of container of flot graph.
         ".detail {\n"
         "  margin: 0px;\n"
@@ -93,13 +97,13 @@ void PutVarsHeading(std::ostream& os, bool expand_all) {
 
         "function prepareGraphs() {\n"
         // Hide all graphs at first.
-        "  $(\".detail\").hide();\n"
+        "  $(\".detail-row\").hide();\n"
 
         // Register clicking functions.
         "  $(\".variable\").click(function() {\n"
-        "    var mod = $(this).next(\".detail\");\n"
+        "    var mod = $(this).next(\".detail-row\");\n"
         "    mod.slideToggle(\"fast\");\n"
-        "    var var_name = mod.children(\":first-child\").attr(\"id\");\n"
+        "    var var_name = 
mod.find(\".detail\").children(\":first-child\").attr(\"id\");\n"
         "    if (!everEnabled[var_name]) {\n"
         "      everEnabled[var_name] = true;\n"
         // Create tooltip at first click.
@@ -272,21 +276,24 @@ public:
                 name, _os, series_options);
             plot = (rc == 0);
             if (plot) {
-                _os << "<p class=\"variable\">";
+                _os << "<tr class=\"variable\">";
             } else {
-                _os << "<p class=\"nonplot-variable\">";
+                _os << "<tr class=\"nonplot-variable\">";
             }
         }
-        _os << name << VAR_SEP;
         if (_use_html) {
-            _os << "<span id=\"value-" << name << "\">";
+            _os << "<td>" << name << "</td><td><span id=\"value-" << name << 
"\">";
+        } else {
+            _os << name << VAR_SEP;
         }
         _os << desc;
         if (_use_html) {
-            _os << "</span></p>\n";
+            _os << "</span></td></tr>\n";
             if (plot) {
-                _os << "<div class=\"detail\"><div id=\"" << name
-                     << "\" class=\"flot-placeholder\"></div></div>\n";
+                _os << "<tr class=\"detail-row\"><td colspan=\"2\">"
+                    "<div class=\"detail\"><div id=\"" << name
+                    << "\" class=\"flot-placeholder\"></div></div>"
+                    "</td></tr>\n";
             }
         } else {
             _os << "\r\n";
@@ -369,7 +376,7 @@ void 
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
             "    enabled = {};\n"
             "    everEnabled = {};\n"
             "  }\n"
-            "  $(\".detail\").hide();\n"
+            "  $(\".detail-row\").hide();\n"
             "  $('#layer1').html(data);\n"
             "  prepareGraphs();\n"
             "  window.history.pushState('', '', toURL(searchText));\n"
@@ -406,7 +413,10 @@ void 
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
         os << "<p>Search : <input id='searchbox' type='text'"
             " onkeyup='onQueryChanged()'></p>"
             "<div id=\"layer1\">\n";
-    }    
+    }
+    if (use_html) {
+        os << "<table class=\"gridtable\" 
border=\"1\"><tr><th>Name</th><th>Value</th></tr>\n";
+    }
     VarsDumper dumper(os, use_html);
     bvar::DumpOptions options;
     options.question_mark = '$';
@@ -422,6 +432,9 @@ void 
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
         cntl->SetFailed(ENOMETHOD, "Fail to find any bvar by `%s'",
                         options.white_wildcards.c_str());
     }
+    if (use_html) {
+        os << "</table>";
+    }
     if (with_tabs) {
         os << "</div></body></html>";
     }
diff --git a/test/brpc_builtin_service_unittest.cpp 
b/test/brpc_builtin_service_unittest.cpp
index e4f61e70..e496c05f 100644
--- a/test/brpc_builtin_service_unittest.cpp
+++ b/test/brpc_builtin_service_unittest.cpp
@@ -697,15 +697,33 @@ TEST_F(BuiltinServiceTest, vars) {
     brpc::VarsService service;
     brpc::VarsRequest req;
     brpc::VarsResponse res;
+    bvar::Adder<int64_t> myvar;
+    myvar.expose("myvar");
+    myvar << 9;
     {
         ClosureChecker done;
         brpc::Controller cntl;
-        bvar::Adder<int64_t> myvar;
-        myvar.expose("myvar");
-        myvar << 9;
         service.default_method(&cntl, &req, &res, &done);
         EXPECT_FALSE(cntl.Failed());
+        EXPECT_EQ("text/plain", cntl.http_response().content_type());
         CheckFieldInContent(cntl, "myvar : ", 9);
+        EXPECT_EQ(std::string::npos,
+                  cntl.response_attachment().to_string().find("<table"));
+    }
+    {
+        ClosureChecker done;
+        brpc::Controller cntl;
+        SetUpController(&cntl, true);
+        cntl.http_request()._unresolved_path = "myvar";
+        service.default_method(&cntl, &req, &res, &done);
+        EXPECT_FALSE(cntl.Failed());
+        EXPECT_EQ("text/html", cntl.http_response().content_type());
+        CheckContent(cntl,
+                     "<table class=\"gridtable\" 
border=\"1\"><tr><th>Name</th><th>Value</th></tr>");
+        CheckContent(cntl,
+                     "<tr class=\"variable\"><td>myvar</td><td><span 
id=\"value-myvar\">9</span></td></tr>");
+        CheckContent(cntl,
+                     "<tr class=\"detail-row\"><td colspan=\"2\"><div 
class=\"detail\"><div id=\"myvar\" 
class=\"flot-placeholder\"></div></div></td></tr>");
     }
     {
         ClosureChecker done;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to