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);
}