remote/CefSettingsParser.cpp (225 lines of code) (raw):
#include "CefSettingsParser.h"
#include <fstream>
#include <algorithm>
#include "Utils.h"
#include "log/Log.h"
namespace {
const bool doTrace = getBoolEnv("CEF_SERVER_TRACE_CefSettingsParser");
const std::string SPACE = "_SPACESYMBOL_";
template <typename T>
bool stoi_safe(std::string arg, T & out) {
try {
out = std::stoi(arg);
return true;
} catch (const std::exception&) {
Log::warn("Can't parse integer from string '%s'", arg.c_str());
}
return false;
}
bool parseSettingLine(const std::string & settingLine, std::vector<std::pair<std::string, std::string>> & out) {
auto pos = settingLine.find('=', 1);
if (pos == settingLine.npos) {
Log::warn("Can't parse setting line: %s", settingLine.c_str());
return false;
}
std::string name = settingLine.substr(0, pos);
std::string val = settingLine.substr(pos + 1);
if (doTrace)
Log::trace("\t parseSettingLine: name=%s val=%s", name.c_str(), val.c_str());
out.push_back(std::pair<std::string, std::string>(name, val));
return true;
}
bool parseSchemeLine(const std::string & settingLine, std::string & name, int & options) {
auto pos = settingLine.find("|");
if (pos == settingLine.npos) {
Log::warn("Can't parse scheme line: %s", settingLine.c_str());
return false;
}
name.assign(settingLine.substr(0, pos - 1));
stoi_safe(settingLine.substr(pos + 1), options);
return true;
}
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
}
namespace CefSettingsParser {
bool setSettingItem(CefSettings & out, const std::string & name, const std::string & val) {
//
// Fill string fields
//
size_t cachedPos = name.npos;
if (name.find("browser_subprocess_path") != name.npos) {
CefString(&out.browser_subprocess_path) = val;
} else if (name.find("cache_path") != name.npos) {
CefString(&out.cache_path) = val;
} else if (name.find("user_agent_product") != name.npos) {
CefString(&out.user_agent_product) = val;
} else if (name.find("user_agent") != name.npos) {
CefString(&out.user_agent) = val;
} else if (name.find("locales_dir_path") != name.npos) {
CefString(&out.locales_dir_path) = val;
} else if ((cachedPos = name.find("locale")) != name.npos && (name[cachedPos + 6] == ' ' || name[cachedPos + 6] == '=')) {
CefString(&out.locale) = val;
} else if (name.find("log_file") != name.npos) {
CefString(&out.log_file) = val;
} else if (name.find("log_severity") != name.npos) {
std::string valLowerCase = val;
std::transform(valLowerCase.begin(), valLowerCase.end(), valLowerCase.begin(),
[](unsigned char in){
if (in <= 'Z' && in >= 'A')
return in - ('Z' - 'z');
return (int)in;
});
if (valLowerCase.find("verb") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_VERBOSE;
else if (valLowerCase.find("debug") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_DEBUG;
else if (valLowerCase.find("info") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_INFO;
else if (valLowerCase.find("warn") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_WARNING;
else if (valLowerCase.find("err") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_ERROR;
else if (valLowerCase.find("disable") != valLowerCase.npos)
out.log_severity = LOGSEVERITY_DISABLE;
else
out.log_severity = LOGSEVERITY_DEFAULT;
} else if (name.find("javascript_flags") != name.npos) {
CefString(&out.javascript_flags) = val;
} else if (name.find("resources_dir_path") != name.npos) {
CefString(&out.resources_dir_path) = val;
} else if (name.find("cookieable_schemes_list") != name.npos) {
CefString(&out.cookieable_schemes_list) = val;
} else if (name.find("windowless_rendering_enabled") != name.npos) {
//
// Fill bool fields
//
if (val.compare("true") != 0)
Log::trace("Setting 'windowless_rendering_enabled' will be ignored");
} else if (name.find("command_line_args_disabled") != name.npos) {
out.command_line_args_disabled = val.compare("true") == 0;
} else if (name.find("persist_session_cookies") != name.npos) {
out.persist_session_cookies = val.compare("true") == 0;
} else if (name.find("cookieable_schemes_exclude_defaults") != name.npos) {
out.cookieable_schemes_exclude_defaults = val.compare("true") == 0;
} else if (name.find("no_sandbox") != name.npos) {
out.no_sandbox = val.compare("true") == 0;
} else if (name.find("remote_debugging_port") != name.npos) {
//
// Fill int fields
//
stoi_safe(val, out.remote_debugging_port);
} else if (name.find("uncaught_exception_stack_size") != name.npos) {
stoi_safe(val, out.uncaught_exception_stack_size);
} else if (name.find("background_color") != name.npos) {
stoi_safe(val, out.background_color);
} else {
Log::warn("Unknown CefSetting item: %s=%s", name.c_str(), val.c_str());
return false;
}
return true;
}
bool parseCefSettingWord(const std::string & arg, std::vector<std::pair<std::string, std::string>> & out) {
const std::string prefixes[] = {"cs:", "cef_setting:"};
std::string name;
std::string val;
for (auto prefix: prefixes) {
const auto pos = arg.find(prefix);
if (pos == arg.npos)
continue;
const auto eqPos = arg.find("=", pos);
if (eqPos == arg.npos)
continue;
const auto startPos = pos + prefix.size();
name.assign(arg.substr(startPos, eqPos - startPos));
val.assign(arg.substr(eqPos + 1));
replaceAll(val, SPACE, " ");
break;
}
if (name.empty()) {
// Log::trace("Can't parse cef-setting word: %s", arg.c_str());
return false;
}
if (doTrace)
Log::trace("\t parseCefSettingWord: parsed name=%s val='%s'", name.c_str(), val.c_str());
out.push_back(std::pair<std::string, std::string>(name, val));
return true;
}
bool parseCefSchemeWord(const std::string & arg, std::string & name, int & options) {
const std::string prefixes[] = {"sch:", "customscheme:"};
name = "";
options = 0;
for (auto prefix: prefixes) {
const auto pos = arg.find(prefix);
if (pos == arg.npos)
continue;
const auto eqPos = arg.find("=", pos);
if (eqPos == arg.npos)
continue;
const auto startPos = pos + prefix.size();
name.assign(arg.substr(startPos, eqPos - startPos));
stoi_safe(arg.substr(eqPos + 1), options);
break;
}
if (name.empty()) {
// Log::trace("Can't parse cef-scheme word: %s", arg.c_str());
return false;
}
if (doTrace)
Log::trace("\t parseCefSchemeWord: parsed name=%s options=%d", name.c_str(), options);
return true;
}
bool parseCefCmdLineSwitch(const std::string & arg, std::string & out) {
const std::string prefixes[] = {"arg:", "cmd_switch:"};
out = "";
for (auto prefix: prefixes) {
const auto pos = arg.find(prefix);
if (pos == arg.npos)
continue;
out.assign(arg.substr(pos + prefix.size()));
replaceAll(out, SPACE, " ");
break;
}
if (out.empty()) {
// Log::trace("Can't parse cef-switch word: %s", arg.c_str());
return false;
}
if (doTrace)
Log::trace("\t parseCefCmdLineSwitch: parsed %s", out.c_str());
return true;
}
void parseParamsFile(const std::string & paramsFilePath, std::vector<std::string> & cmdlineSwitches/*output*/, std::vector<std::pair<std::string, std::string>> & parsedSettings/*output*/, std::vector<std::pair<std::string, int>> & schemes/*output*/) {
bool collectCmdSwitches = false;
bool collectSettings = false;
bool collectSchemes = false;
if (!paramsFilePath.empty()) {
std::ifstream infile(paramsFilePath);
std::string line;
while (std::getline(infile, line)) {
if (doTrace)
Log::trace("\tprocess settings line: %s", line.c_str());
if (line.empty() || line[0] == '#')
continue;
if (line.find("[COMMAND_LINE]:") != line.npos) {
collectCmdSwitches = true;
collectSettings = collectSchemes = false;
} else if (line.find("[SETTINGS]:") != line.npos) {
collectSettings = true;
collectSchemes = collectCmdSwitches = false;
} else if (line.find("[CUSTOM_SCHEMES]:") != line.npos) {
collectSchemes = true;
collectSettings = collectCmdSwitches = false;
} else {
if (!collectCmdSwitches && !collectSettings && !collectSchemes) {
Log::warn("Parse file with params: skip unknown line %s", line.c_str());
} else if (collectCmdSwitches) {
cmdlineSwitches.push_back(line);
} else if (collectSettings) {
parseSettingLine(line, parsedSettings);
} else {
std::string name;
int options;
if (parseSchemeLine(line, name, options))
schemes.push_back(std::make_pair(name, options));
}
}
}
} else
Log::debug("Params file is empty.");
}
} // CefSettingsParser