void FlagsService::default_method()

in src/brpc/builtin/flags_service.cpp [135:249]


void FlagsService::default_method(::google::protobuf::RpcController* cntl_base,
                                  const ::brpc::FlagsRequest*,
                                  ::brpc::FlagsResponse*,
                                  ::google::protobuf::Closure* done) {
    ClosureGuard done_guard(done);
    Controller *cntl = static_cast<Controller*>(cntl_base);
    const std::string* value_str =
        cntl->http_request().uri().GetQuery(SETVALUE_STR);
    const std::string& constraint = cntl->http_request().unresolved_path();

    const bool use_html = UseHTML(cntl->http_request());
    cntl->http_response().set_content_type(
        use_html ? "text/html" : "text/plain");

    if (value_str != NULL) {
        // reload value if ?setvalue=VALUE is present.
        if (constraint.empty()) {
            cntl->SetFailed(ENOMETHOD, "Require gflag name");
            return;
        }
        if (use_html && cntl->http_request().uri().GetQuery("withform")) {
            return set_value_page(cntl, done_guard.release());
        }
        GFLAGS_NAMESPACE::CommandLineFlagInfo info;
        if (!GFLAGS_NAMESPACE::GetCommandLineFlagInfo(constraint.c_str(), &info)) {
            cntl->SetFailed(ENOMETHOD, "No such gflag");
            return;
        }
        if (!info.has_validator_fn) {
            cntl->SetFailed(EPERM, "A reloadable gflag must have validator");
            return;
        }
        if (FLAGS_immutable_flags) {
            cntl->SetFailed(EPERM, "Cannot modify `%s' because -immutable_flags is on",
                            constraint.c_str());
            return;
        }
        if (GFLAGS_NAMESPACE::SetCommandLineOption(constraint.c_str(),
                                                   value_str->c_str()).empty()) {
            cntl->SetFailed(EPERM, "Fail to set `%s' to %s",
                            constraint.c_str(),
                            (value_str->empty() ? "empty string" : value_str->c_str()));
            return;
        }
        butil::IOBufBuilder os;
        os << "Set `" << constraint << "' to " << *value_str;
        if (use_html) {
            os << "<br><a href='/flags'>[back to flags]</a>";
        }
        os.move_to(cntl->response_attachment());
        return;
    }

    // Parse query-string which is comma-separated flagnames/wildcards.
    std::vector<std::string> wildcards;
    std::set<std::string> exact;
    if (!constraint.empty()) {
        for (butil::StringMultiSplitter sp(constraint.c_str(), ",;"); sp != NULL; ++sp) {
            std::string name(sp.field(), sp.length());
            if (name.find_first_of("$*") != std::string::npos) {
                wildcards.push_back(name);
            } else {
                exact.insert(name);
            }
        }
    }

    // Print header of the table
    butil::IOBufBuilder os;
    if (use_html) {
        os << "<!DOCTYPE html><html><head>\n" << gridtable_style()
           << "<script language=\"javascript\" type=\"text/javascript\" src=\"/js/jquery_min\"></script>\n"
           << TabsHead()
           << "</head><body>";
        cntl->server()->PrintTabsBody(os, "flags");
        os << "<table class=\"gridtable\" border=\"1\"><tr><th>Name</th><th>Value</th>"
            "<th>Description</th><th>Defined At</th></tr>\n";
    } else {
        os << "Name | Value | Description | Defined At\n"
              "---------------------------------------\n";
    }

    if (!constraint.empty() && wildcards.empty()) {
        // Only exact names. We don't have to iterate all flags in this case.
        for (std::set<std::string>::iterator it = exact.begin();
             it != exact.end(); ++it) {
            GFLAGS_NAMESPACE::CommandLineFlagInfo info;
            if (GFLAGS_NAMESPACE::GetCommandLineFlagInfo(it->c_str(), &info)) {
                PrintFlag(os, info, use_html);
                os << '\n';
            }
        }

    } else {
        // Iterate all flags and filter.
        std::vector<GFLAGS_NAMESPACE::CommandLineFlagInfo> flag_list;
        flag_list.reserve(128);
        GFLAGS_NAMESPACE::GetAllFlags(&flag_list);
        for (std::vector<GFLAGS_NAMESPACE::CommandLineFlagInfo>::iterator
                 it = flag_list.begin(); it != flag_list.end(); ++it) {
            if (!constraint.empty() &&
                exact.find(it->name) == exact.end() &&
                !MatchAnyWildcard(it->name, wildcards)) {
                continue;
            }
            PrintFlag(os, *it, use_html);
            os << '\n';
        }
    }
    if (use_html) {
        os << "</table></body></html>\n";
    }
    os.move_to(cntl->response_attachment());
    cntl->set_response_compress_type(COMPRESS_TYPE_GZIP);
}