void VarsService::default_method()

in src/brpc/builtin/vars_service.cpp [308:430]


void VarsService::default_method(::google::protobuf::RpcController* cntl_base,
                                 const ::brpc::VarsRequest*,
                                 ::brpc::VarsResponse*,
                                 ::google::protobuf::Closure* done) {
    ClosureGuard done_guard(done);
    Controller *cntl = static_cast<Controller*>(cntl_base);    
    if (cntl->http_request().uri().GetQuery("series") != NULL) {
        butil::IOBufBuilder os;
        bvar::SeriesOptions series_options;
        const int rc = bvar::Variable::describe_series_exposed(
            cntl->http_request().unresolved_path(), os, series_options);
        if (rc == 0) {
            cntl->http_response().set_content_type("application/json");
            os.move_to(cntl->response_attachment());
        } else if (rc < 0) {
            cntl->SetFailed(ENOMETHOD, "Fail to find any bvar by `%s'",
                            cntl->http_request().unresolved_path().c_str());
        } else {
            cntl->SetFailed(ENODATA, "`%s' does not have value series",
                            cntl->http_request().unresolved_path().c_str());
        }
        return;
    }
    const bool use_html = UseHTML(cntl->http_request());
    bool with_tabs = false;
    if (use_html && cntl->http_request().uri().GetQuery("dataonly") == NULL) {
        with_tabs = true;
    }
    cntl->http_response().set_content_type(
        use_html ? "text/html" : "text/plain");

    butil::IOBufBuilder os;
    if (with_tabs) {
        os << "<!DOCTYPE html><html><head>\n"
            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n";
        PutVarsHeading(os, cntl->http_request().uri().GetQuery("expand"));
        os << "<script type=\"text/javascript\">\n"
            "const delayTime = 200;\n"
            "var searching = false;\n"
            "function toURL(text) {\n"
            "  if (text == '') {\n"
            "    return '/vars';\n"
            "  }\n"
            // Normalize ;,\s\* to space, trim beginning/ending spaces and
            // replace all spaces with *;* and add beginning/ending *
            //   iobuf,bthread         -> *iobuf*;*bthread*
            //   iobuf,                -> *iobuf*
            //   ;,iobuf               -> *iobuf*
            //   ,;*iobuf*, bthread;,; -> *iobuf*;*bthread*
            "  text = text.replace(/(;|,|\\s|\\*)+/g, ' ').trim()"
            "             .replace(/ /g, '*;*');\n"
            "  if (text == '') {\n"
            "    return '/vars';\n"
            "  }\n"
            "  return '/vars/*' + text + '*';\n"
            "}\n"
            "function onDataReceived(searchText, data) {\n"
            "  for (var var_name in enabled) {\n"
            "    if (enabled[var_name]) {\n"
            "      clearTimeout(timeoutId[var_name]);\n"
            "    }\n"
            "    enabled = {};\n"
            "    everEnabled = {};\n"
            "  }\n"
            "  $(\".detail\").hide();\n"
            "  $('#layer1').html(data);\n"
            "  prepareGraphs();\n"
            "  window.history.pushState('', '', toURL(searchText));\n"
            "  var newSearchText = $('#searchbox').val();\n"
            "  if (newSearchText != searchText) {\n"
            "    setTimeout(search, delayTime);\n"
            "    console.log('text changed during searching, search again');\n"
            "  } else {\n"
            "    searching = false;\n"
            "  }\n"
            "}\n"
            "function search() {\n"
            "  var searchText = $('#searchbox').val();\n"
            "  $.ajax({\n"
            "    url: toURL(searchText) + '?dataonly',\n"
            "    type: \"GET\",\n"
            "    dataType: \"html\",\n"
            "    success: function(data) { onDataReceived(searchText, data); },\n"
            "    error: function(xhr, ajaxOptions, thrownError) {\n"
            "             onDataReceived(searchText, xhr.responseText);\n"
            "           }\n"
            "  });\n"
            "}\n"
            "function onQueryChanged() {\n"
            "  if (searching) {\n"
            "    return;\n"
            "  }\n"
            "  searching = true;\n"
            "  setTimeout(search, delayTime);\n"
            "}\n"
            "</script>\n"
            "</head>\n<body>\n";
        cntl->server()->PrintTabsBody(os, "vars");
        os << "<p>Search : <input id='searchbox' type='text'"
            " onkeyup='onQueryChanged()'></p>"
            "<div id=\"layer1\">\n";
    }    
    VarsDumper dumper(os, use_html);
    bvar::DumpOptions options;
    options.question_mark = '$';
    options.display_filter = 
        (use_html ? bvar::DISPLAY_ON_HTML : bvar::DISPLAY_ON_PLAIN_TEXT);
    options.white_wildcards = cntl->http_request().unresolved_path();
    const int ndump = bvar::Variable::dump_exposed(&dumper, &options);
    if (ndump < 0) {
        cntl->SetFailed("Fail to dump vars");
        return;
    }
    if (!options.white_wildcards.empty() && ndump == 0) {
        cntl->SetFailed(ENOMETHOD, "Fail to find any bvar by `%s'",
                        options.white_wildcards.c_str());
    }
    if (with_tabs) {
        os << "</div></body></html>";
    }
    os.move_to(cntl->response_attachment());
    cntl->set_response_compress_type(COMPRESS_TYPE_GZIP);
}