ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header) { String::SizeType pos = auth_header.FindFirstOf(" "); String username, password; if (pos != String::NPos && auth_header.SubStr(0, pos) == "Basic") { String credentials_base64 = auth_header.SubStr(pos + 1); String credentials = Base64::Decode(credentials_base64); String::SizeType cpos = credentials.FindFirstOf(":"); if (cpos != String::NPos) { username = credentials.SubStr(0, cpos); password = credentials.SubStr(cpos + 1); } } const ApiUser::Ptr& user = ApiUser::GetByName(username); /* Deny authentication if: * 1) user does not exist * 2) given password is empty * 2) configured password does not match. */ if (!user || password.IsEmpty()) return nullptr; else if (user && user->GetPassword() != password) return nullptr; return user; }
void LegacyTimePeriod::ParseTimeRange(const String& timerange, tm *begin, tm *end, int *stride, tm *reference) { String def = timerange; /* Figure out the stride. */ size_t pos = def.FindFirstOf('/'); if (pos != String::NPos) { String strStride = def.SubStr(pos + 1).Trim(); *stride = Convert::ToLong(strStride); /* Remove the stride parameter from the definition. */ def = def.SubStr(0, pos); } else { *stride = 1; /* User didn't specify anything, assume default. */ } /* Figure out whether the user has specified two dates. */ pos = def.Find("- "); if (pos != String::NPos) { String first = def.SubStr(0, pos).Trim(); String second = def.SubStr(pos + 1).Trim(); ParseTimeSpec(first, begin, NULL, reference); /* If the second definition starts with a number we need * to add the first word from the first definition, e.g.: * day 1 - 15 --> "day 15" */ bool is_number = true; size_t xpos = second.FindFirstOf(' '); String fword = second.SubStr(0, xpos); try { Convert::ToLong(fword); } catch (...) { is_number = false; } if (is_number) { xpos = first.FindFirstOf(' '); ASSERT(xpos != String::NPos); second = first.SubStr(0, xpos + 1) + second; } ParseTimeSpec(second, NULL, end, reference); } else { ParseTimeSpec(def, begin, end, reference); } }
kt_bool StringHelper::FromString(const String& rStringValue, Quaternion& rValue) { kt_size_t index = rStringValue.FindFirstOf(" "); if (index != -1) { std::stringstream converter; converter.str(rStringValue.ToCString()); kt_double valueX = 0.0; kt_double valueY = 0.0; kt_double valueZ = 0.0; kt_double valueW = 0.0; converter >> valueX; converter >> valueY; converter >> valueZ; converter >> valueW; rValue.SetX(valueX); rValue.SetY(valueY); rValue.SetZ(valueZ); rValue.SetW(valueW); return true; }
Url::Url(const String& base_url) { String url = base_url; if (url.GetLength() == 0) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Empty URL.")); size_t pHelper = url.Find(":"); if (pHelper != String::NPos) { if (!ParseScheme(url.SubStr(0, pHelper))) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Scheme.")); url = url.SubStr(pHelper + 1); } if (*url.Begin() != '/') BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: '/' expected after scheme.")); if (url.GetLength() == 1) { return; } if (*(url.Begin() + 1) == '/') { pHelper = url.Find("/", 2); if (pHelper == String::NPos) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: Missing '/' after authority.")); if (!ParseAuthority(url.SubStr(0, pHelper))) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Authority")); url = url.SubStr(pHelper); } if (*url.Begin() == '/') { pHelper = url.FindFirstOf("#?"); if (!ParsePath(url.SubStr(1, pHelper - 1))) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Path")); if (pHelper != String::NPos) url = url.SubStr(pHelper); } else BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: Missing path.")); if (*url.Begin() == '?') { pHelper = url.Find("#"); if (!ParseQuery(url.SubStr(1, pHelper - 1))) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Query")); if (pHelper != String::NPos) url = url.SubStr(pHelper); } if (*url.Begin() == '#') { if (!ParseFragment(url.SubStr(1))) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Fragment")); } }
bool Url::ParseScheme(const String& scheme) { m_Scheme = scheme; if (scheme.FindFirstOf(ALPHA) != 0) return false; return (ValidateToken(scheme, ACSCHEME)); }
bool Url::ValidateToken(const String& token, const String& symbols) { for (const char ch : token) { if (symbols.FindFirstOf(ch) == String::NPos) return false; } return true; }
void HttpConnection::ProcessMessageAsync(HttpRequest& request) { Log(LogInformation, "HttpConnection", "Processing Http message"); String auth_header = request.Headers->Get("authorization"); String::SizeType pos = auth_header.FindFirstOf(" "); String username, password; if (pos != String::NPos && auth_header.SubStr(0, pos) == "Basic") { String credentials_base64 = auth_header.SubStr(pos + 1); String credentials = Base64::Decode(credentials_base64); String::SizeType cpos = credentials.FindFirstOf(":"); if (cpos != String::NPos) { username = credentials.SubStr(0, cpos); password = credentials.SubStr(cpos + 1); } } ApiUser::Ptr user; if (m_ApiUser) user = m_ApiUser; else { user = ApiUser::GetByName(username); if (!user || !user->CheckPassword(password)) user.reset(); } HttpResponse response(m_Stream, request); if (!user) { response.SetStatus(401, "Unauthorized"); response.AddHeader("Content-Type", "text/html"); response.AddHeader("WWW-Authenticate", "Basic realm=\"Icinga 2\""); String msg = "<h1>Unauthorized</h1>"; response.WriteBody(msg.CStr(), msg.GetLength()); } else { try { HttpHandler::ProcessRequest(user, request, response); } catch (const std::exception& ex) { response.SetStatus(503, "Unhandled exception"); response.AddHeader("Content-Type", "text/plain"); String errorInfo = DiagnosticInformation(ex); response.WriteBody(errorInfo.CStr(), errorInfo.GetLength()); } } response.Finish(); m_PendingRequests--; }
static String LoadAppType(const String& typeSpec) { int index; Log(LogInformation, "icinga-app", "Loading application type: " + typeSpec); index = typeSpec.FindFirstOf('/'); if (index == String::NPos) return typeSpec; String library = typeSpec.SubStr(0, index); (void) Utility::LoadExtensionLibrary(library); return typeSpec.SubStr(index + 1); }
static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter, const String& zone, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo()) { ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo); String checkName = name; if (!abstract) { Type::Ptr ptype = Type::GetByName(type); NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get()); if (nc) checkName = nc->MakeName(name, Dictionary::Ptr()); } if (!checkName.IsEmpty()) { ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName); if (oldItem) { std::ostringstream msgbuf; msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo(); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo)); } } item->SetType(type); if (name.FindFirstOf("!") != String::NPos) { std::ostringstream msgbuf; msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'"; BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo)); } item->SetName(name); item->AddExpression(new OwnedExpression(expression)); item->SetAbstract(abstract); item->SetScope(EvaluateClosedVars(frame, closedVars)); item->SetZone(zone); item->SetFilter(filter); item->Compile()->Register(); return Empty; }
String Utility::EscapeShellCmd(const String& s) { String result; size_t prev_quote = String::NPos; int index = -1; BOOST_FOREACH(char ch, s) { bool escape = false; index++; #ifdef _WIN32 if (ch == '%' || ch == '"' || ch == '\'') escape = true; #else /* _WIN32 */ if (ch == '"' || ch == '\'') { /* Find a matching closing quotation character. */ if (prev_quote == String::NPos && (prev_quote = s.FindFirstOf(ch, index + 1)) != String::NPos) ; /* Empty statement. */ else if (prev_quote != String::NPos && s[prev_quote] == ch) prev_quote = String::NPos; else escape = true; } #endif /* _WIN32 */ if (ch == '#' || ch == '&' || ch == ';' || ch == '`' || ch == '|' || ch == '*' || ch == '?' || ch == '~' || ch == '<' || ch == '>' || ch == '^' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}' || ch == '$' || ch == '\\' || ch == '\x0A' || ch == '\xFF') escape = true; if (escape) #ifdef _WIN32 result += '^'; #else /* _WIN32 */ result += '\\'; #endif /* _WIN32 */ result += ch; }
NAMESPACE_UPP #ifdef PLATFORM_WIN32 static void fixSpecials(String &s) { // this stuff just for windows... sig if(s.FindFirstOf(" \t\n\v\"") >= 0) { String sOld = s; s.Clear(); s = "\""; const char *sp = sOld; for(;;) { int num_backslashes = 0; while(*sp == '\\') { sp++; num_backslashes++; } if(*sp == '\0') { s.Cat('\\', 2 * num_backslashes); break; } else if(*sp == '\"') { s.Cat('\\', 2 * num_backslashes + 1); s << '\"'; } else { s.Cat('\\', num_backslashes); s.Cat(*sp); } sp++; } s << '\"'; } }
bool HttpRequest::Parse(StreamReadContext& src, bool may_wait) { if (m_State != HttpRequestBody) { String line; StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait); if (srs != StatusNewItem) return false; if (m_State == HttpRequestStart) { /* ignore trailing new-lines */ if (line == "") return true; std::vector<String> tokens; boost::algorithm::split(tokens, line, boost::is_any_of(" ")); Log(LogDebug, "HttpRequest") << "line: " << line << ", tokens: " << tokens.size(); if (tokens.size() != 3) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request")); RequestMethod = tokens[0]; RequestUrl = new class Url(tokens[1]); if (tokens[2] == "HTTP/1.0") ProtocolVersion = HttpVersion10; else if (tokens[2] == "HTTP/1.1") { ProtocolVersion = HttpVersion11; } else BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version")); m_State = HttpRequestHeaders; } else if (m_State == HttpRequestHeaders) { if (line == "") { m_State = HttpRequestBody; /* we're done if the request doesn't contain a message body */ if (!Headers->Contains("content-length") && !Headers->Contains("transfer-encoding")) Complete = true; else m_Body = new FIFO(); return true; } else { String::SizeType pos = line.FindFirstOf(":"); if (pos == String::NPos) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request")); String key = line.SubStr(0, pos).ToLower().Trim(); String value = line.SubStr(pos + 1).Trim(); Headers->Set(key, value); if (key == "x-http-method-override") RequestMethod = value; } } else { VERIFY(!"Invalid HTTP request state."); } } else if (m_State == HttpRequestBody) { if (Headers->Get("transfer-encoding") == "chunked") { if (!m_ChunkContext) m_ChunkContext = boost::make_shared<ChunkReadContext>(src); char *data; size_t size; StreamReadStatus srs = HttpChunkedEncoding::ReadChunkFromStream(m_Stream, &data, &size, *m_ChunkContext.get(), may_wait); if (srs != StatusNewItem) return false; Log(LogInformation, "HttpRequest") << "Read " << size << " bytes"; m_Body->Write(data, size); delete [] data; if (size == 0) { Complete = true; return true; } } else { if (src.Eof) BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body")); if (src.MustRead) { if (!src.FillFromStream(m_Stream, false)) { src.Eof = true; BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body")); } src.MustRead = false; } size_t length_indicator = Convert::ToLong(Headers->Get("content-length")); if (src.Size < length_indicator) { src.MustRead = true; return false; } m_Body->Write(src.Buffer, length_indicator); src.DropData(length_indicator); Complete = true; return true; } } return true; }
bool HttpRequest::ParseHeaders(StreamReadContext& src, bool may_wait) { if (!m_Stream) return false; if (m_State != HttpRequestStart && m_State != HttpRequestHeaders) BOOST_THROW_EXCEPTION(std::runtime_error("Invalid HTTP state")); String line; StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait); if (srs != StatusNewItem) { if (src.Size > 8 * 1024) BOOST_THROW_EXCEPTION(std::invalid_argument("Line length for HTTP header exceeded")); return false; } if (line.GetLength() > 8 * 1024) { #ifdef I2_DEBUG /* I2_DEBUG */ Log(LogDebug, "HttpRequest") << "Header size: " << line.GetLength() << " content: '" << line << "'."; #endif /* I2_DEBUG */ BOOST_THROW_EXCEPTION(std::invalid_argument("Line length for HTTP header exceeded")); } if (m_State == HttpRequestStart) { /* ignore trailing new-lines */ if (line == "") return true; std::vector<String> tokens = line.Split(" "); Log(LogDebug, "HttpRequest") << "line: " << line << ", tokens: " << tokens.size(); if (tokens.size() != 3) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request")); RequestMethod = tokens[0]; RequestUrl = new class Url(tokens[1]); if (tokens[2] == "HTTP/1.0") ProtocolVersion = HttpVersion10; else if (tokens[2] == "HTTP/1.1") { ProtocolVersion = HttpVersion11; } else BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version")); m_State = HttpRequestHeaders; return true; } else { // m_State = HttpRequestHeaders if (line == "") { m_State = HttpRequestBody; CompleteHeaders = true; return true; } else { if (Headers->GetLength() > 128) BOOST_THROW_EXCEPTION(std::invalid_argument("Maximum number of HTTP request headers exceeded")); String::SizeType pos = line.FindFirstOf(":"); if (pos == String::NPos) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request")); String key = line.SubStr(0, pos).ToLower().Trim(); String value = line.SubStr(pos + 1).Trim(); Headers->Set(key, value); if (key == "x-http-method-override") RequestMethod = value; return true; } } }
/** * Handles an include directive. * * @param include The path from the include directive. * @param search Whether to search global include dirs. * @param debuginfo Debug information. */ void ConfigCompiler::HandleInclude(const String& include, bool search, const DebugInfo& debuginfo) { String path; if (search || (include.GetLength() > 0 && include[0] == '/')) path = include; else path = Utility::DirName(GetPath()) + "/" + include; String includePath = path; if (search) { BOOST_FOREACH(const String& dir, m_IncludeSearchDirs) { String spath = dir + "/" + include; #ifndef _WIN32 struct stat statbuf; if (lstat(spath.CStr(), &statbuf) >= 0) { #else /* _WIN32 */ struct _stat statbuf; if (_stat(spath.CStr(), &statbuf) >= 0) { #endif /* _WIN32 */ includePath = spath; break; } } } std::vector<ConfigItem::Ptr> items; if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) { std::ostringstream msgbuf; msgbuf << "Include file '" + include + "' does not exist: " << debuginfo; BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str())); } }
Dictionary::Ptr LivestatusLogUtility::GetAttributes(const String& text) { Dictionary::Ptr bag = new Dictionary(); /* * [1379025342] SERVICE NOTIFICATION: contactname;hostname;servicedesc;WARNING;true;foo output */ unsigned long time = atoi(text.SubStr(1, 11).CStr()); Log(LogDebug, "LivestatusLogUtility") << "Processing log line: '" << text << "'."; bag->Set("time", time); size_t colon = text.FindFirstOf(':'); size_t colon_offset = colon - 13; String type = String(text.SubStr(13, colon_offset)).Trim(); String options = String(text.SubStr(colon + 1)).Trim(); bag->Set("type", type); bag->Set("options", options); std::vector<String> tokens = options.Split(";"); /* set default values */ bag->Set("class", LogEntryClassInfo); bag->Set("log_type", 0); bag->Set("state", 0); bag->Set("attempt", 0); bag->Set("message", text); /* used as 'message' in log table, and 'log_output' in statehist table */ if (type.Contains("INITIAL HOST STATE") || type.Contains("CURRENT HOST STATE") || type.Contains("HOST ALERT")) { if (tokens.size() < 5) return bag; bag->Set("host_name", tokens[0]); bag->Set("state", Host::StateFromString(tokens[1])); bag->Set("state_type", tokens[2]); bag->Set("attempt", atoi(tokens[3].CStr())); bag->Set("plugin_output", tokens[4]); if (type.Contains("INITIAL HOST STATE")) { bag->Set("class", LogEntryClassState); bag->Set("log_type", LogEntryTypeHostInitialState); } else if (type.Contains("CURRENT HOST STATE")) { bag->Set("class", LogEntryClassState); bag->Set("log_type", LogEntryTypeHostCurrentState); } else { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeHostAlert); } return bag; } else if (type.Contains("HOST DOWNTIME ALERT") || type.Contains("HOST FLAPPING ALERT")) { if (tokens.size() < 3) return bag; bag->Set("host_name", tokens[0]); bag->Set("state_type", tokens[1]); bag->Set("comment", tokens[2]); if (type.Contains("HOST FLAPPING ALERT")) { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeHostFlapping); } else { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeHostDowntimeAlert); } return bag; } else if (type.Contains("INITIAL SERVICE STATE") || type.Contains("CURRENT SERVICE STATE") || type.Contains("SERVICE ALERT")) { if (tokens.size() < 6) return bag; bag->Set("host_name", tokens[0]); bag->Set("service_description", tokens[1]); bag->Set("state", Service::StateFromString(tokens[2])); bag->Set("state_type", tokens[3]); bag->Set("attempt", atoi(tokens[4].CStr())); bag->Set("plugin_output", tokens[5]); if (type.Contains("INITIAL SERVICE STATE")) { bag->Set("class", LogEntryClassState); bag->Set("log_type", LogEntryTypeServiceInitialState); } else if (type.Contains("CURRENT SERVICE STATE")) { bag->Set("class", LogEntryClassState); bag->Set("log_type", LogEntryTypeServiceCurrentState); } else { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeServiceAlert); } return bag; } else if (type.Contains("SERVICE DOWNTIME ALERT") || type.Contains("SERVICE FLAPPING ALERT")) { if (tokens.size() < 4) return bag; bag->Set("host_name", tokens[0]); bag->Set("service_description", tokens[1]); bag->Set("state_type", tokens[2]); bag->Set("comment", tokens[3]); if (type.Contains("SERVICE FLAPPING ALERT")) { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeServiceFlapping); } else { bag->Set("class", LogEntryClassAlert); bag->Set("log_type", LogEntryTypeServiceDowntimeAlert); } return bag; } else if (type.Contains("TIMEPERIOD TRANSITION")) { if (tokens.size() < 4) return bag; bag->Set("class", LogEntryClassState); bag->Set("log_type", LogEntryTypeTimeperiodTransition); bag->Set("host_name", tokens[0]); bag->Set("service_description", tokens[1]); bag->Set("state_type", tokens[2]); bag->Set("comment", tokens[3]); } else if (type.Contains("HOST NOTIFICATION")) { if (tokens.size() < 6) return bag; bag->Set("contact_name", tokens[0]); bag->Set("host_name", tokens[1]); bag->Set("state_type", tokens[2].CStr()); bag->Set("state", Service::StateFromString(tokens[3])); bag->Set("command_name", tokens[4]); bag->Set("plugin_output", tokens[5]); bag->Set("class", LogEntryClassNotification); bag->Set("log_type", LogEntryTypeHostNotification); return bag; } else if (type.Contains("SERVICE NOTIFICATION")) { if (tokens.size() < 7) return bag; bag->Set("contact_name", tokens[0]); bag->Set("host_name", tokens[1]); bag->Set("service_description", tokens[2]); bag->Set("state_type", tokens[3].CStr()); bag->Set("state", Service::StateFromString(tokens[4])); bag->Set("command_name", tokens[5]); bag->Set("plugin_output", tokens[6]); bag->Set("class", LogEntryClassNotification); bag->Set("log_type", LogEntryTypeServiceNotification); return bag; } else if (type.Contains("PASSIVE HOST CHECK")) { if (tokens.size() < 3) return bag; bag->Set("host_name", tokens[0]); bag->Set("state", Host::StateFromString(tokens[1])); bag->Set("plugin_output", tokens[2]); bag->Set("class", LogEntryClassPassive); return bag; } else if (type.Contains("PASSIVE SERVICE CHECK")) { if (tokens.size() < 4) return bag; bag->Set("host_name", tokens[0]); bag->Set("service_description", tokens[1]); bag->Set("state", Host::StateFromString(tokens[2])); bag->Set("plugin_output", tokens[3]); bag->Set("class", LogEntryClassPassive); return bag; } else if (type.Contains("EXTERNAL COMMAND")) { bag->Set("class", LogEntryClassCommand); /* string processing not implemented in 1.x */ return bag; } else if (type.Contains("LOG VERSION")) { bag->Set("class", LogEntryClassProgram); bag->Set("log_type", LogEntryTypeVersion); return bag; } else if (type.Contains("logging initial states")) { bag->Set("class", LogEntryClassProgram); bag->Set("log_type", LogEntryTypeInitialStates); return bag; } else if (type.Contains("starting... (PID=")) { bag->Set("class", LogEntryClassProgram); bag->Set("log_type", LogEntryTypeProgramStarting); return bag; } /* program */ else if (type.Contains("restarting...") || type.Contains("shutting down...") || type.Contains("Bailing out") || type.Contains("active mode...") || type.Contains("standby mode...")) { bag->Set("class", LogEntryClassProgram); return bag; } return bag; }
PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata) { size_t eqp = perfdata.FindLastOf('='); if (eqp == String::NPos) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data value: " + perfdata)); String label = perfdata.SubStr(0, eqp); if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'') label = label.SubStr(1, label.GetLength() - 2); size_t spq = perfdata.FindFirstOf(' ', eqp); if (spq == String::NPos) spq = perfdata.GetLength(); String valueStr = perfdata.SubStr(eqp + 1, spq - eqp - 1); size_t pos = valueStr.FindFirstNotOf("+-0123456789.e"); double value = Convert::ToDouble(valueStr.SubStr(0, pos)); std::vector<String> tokens = valueStr.Split(";"); bool counter = false; String unit; Value warn, crit, min, max; if (pos != String::NPos) unit = valueStr.SubStr(pos, tokens[0].GetLength() - pos); unit = unit.ToLower(); double base = 1.0; if (unit == "us") { base /= 1000.0 * 1000.0; unit = "seconds"; } else if (unit == "ms") { base /= 1000.0; unit = "seconds"; } else if (unit == "s") { unit = "seconds"; } else if (unit == "tb") { base *= 1024.0 * 1024.0 * 1024.0 * 1024.0; unit = "bytes"; } else if (unit == "gb") { base *= 1024.0 * 1024.0 * 1024.0; unit = "bytes"; } else if (unit == "mb") { base *= 1024.0 * 1024.0; unit = "bytes"; } else if (unit == "kb") { base *= 1024.0; unit = "bytes"; } else if (unit == "b") { unit = "bytes"; } else if (unit == "%") { unit = "percent"; } else if (unit == "c") { counter = true; unit = ""; } else if (unit != "") { BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data unit: " + unit)); } warn = ParseWarnCritMinMaxToken(tokens, 1, "warning"); crit = ParseWarnCritMinMaxToken(tokens, 2, "critical"); min = ParseWarnCritMinMaxToken(tokens, 3, "minimum"); max = ParseWarnCritMinMaxToken(tokens, 4, "maximum"); value = value * base; if (!warn.IsEmpty()) warn = warn * base; if (!crit.IsEmpty()) crit = crit * base; if (!min.IsEmpty()) min = min * base; if (!max.IsEmpty()) max = max * base; return new PerfdataValue(label, value, counter, unit, warn, crit, min, max); }
BOOST_FOREACH(const String& line, lines) { msg += line + "\n"; } Log(LogDebug, "LivestatusQuery", msg); m_CompatLogPath = compat_log_path; /* default separators */ m_Separators.push_back("\n"); m_Separators.push_back(";"); m_Separators.push_back(","); m_Separators.push_back("|"); String line = lines[0]; size_t sp_index = line.FindFirstOf(" "); if (sp_index == String::NPos) BOOST_THROW_EXCEPTION(std::runtime_error("Livestatus header must contain a verb.")); String verb = line.SubStr(0, sp_index); String target = line.SubStr(sp_index + 1); m_Verb = verb; if (m_Verb == "COMMAND") { m_KeepAlive = true; m_Command = target; } else if (m_Verb == "GET") { m_Table = target; } else {
bool HttpResponse::Parse(StreamReadContext& src, bool may_wait) { if (m_State != HttpResponseBody) { String line; StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait); if (srs != StatusNewItem) return false; if (m_State == HttpResponseStart) { /* ignore trailing new-lines */ if (line == "") return true; std::vector<String> tokens = line.Split(" "); Log(LogDebug, "HttpRequest") << "line: " << line << ", tokens: " << tokens.size(); if (tokens.size() < 2) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP response (Status line)")); if (tokens[0] == "HTTP/1.0") ProtocolVersion = HttpVersion10; else if (tokens[0] == "HTTP/1.1") { ProtocolVersion = HttpVersion11; } else BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version")); StatusCode = Convert::ToLong(tokens[1]); if (tokens.size() >= 3) StatusMessage = tokens[2]; // TODO: Join tokens[2..end] m_State = HttpResponseHeaders; } else if (m_State == HttpResponseHeaders) { if (!Headers) Headers = new Dictionary(); if (line == "") { m_State = HttpResponseBody; m_Body = new FIFO(); return true; } else { String::SizeType pos = line.FindFirstOf(":"); if (pos == String::NPos) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request")); String key = line.SubStr(0, pos).ToLower().Trim(); String value = line.SubStr(pos + 1).Trim(); Headers->Set(key, value); } } else { VERIFY(!"Invalid HTTP request state."); } } else if (m_State == HttpResponseBody) { if (Headers->Get("transfer-encoding") == "chunked") { if (!m_ChunkContext) m_ChunkContext = std::make_shared<ChunkReadContext>(std::ref(src)); char *data; size_t size; StreamReadStatus srs = HttpChunkedEncoding::ReadChunkFromStream(m_Stream, &data, &size, *m_ChunkContext.get(), may_wait); if (srs != StatusNewItem) return false; Log(LogNotice, "HttpResponse") << "Read " << size << " bytes"; m_Body->Write(data, size); delete[] data; if (size == 0) { Complete = true; return true; } } else { bool hasLengthIndicator = false; size_t lengthIndicator = 0; Value contentLengthHeader; if (Headers->Get("content-length", &contentLengthHeader)) { hasLengthIndicator = true; lengthIndicator = Convert::ToLong(contentLengthHeader); } if (!hasLengthIndicator && ProtocolVersion != HttpVersion10 && !Headers->Contains("transfer-encoding")) { Complete = true; return true; } if (hasLengthIndicator && src.Eof) BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body")); if (src.MustRead) { if (!src.FillFromStream(m_Stream, may_wait)) src.Eof = true; src.MustRead = false; } if (!hasLengthIndicator) lengthIndicator = src.Size; if (src.Size < lengthIndicator) { src.MustRead = true; return may_wait; } m_Body->Write(src.Buffer, lengthIndicator); src.DropData(lengthIndicator); if (!hasLengthIndicator && !src.Eof) { src.MustRead = true; return may_wait; } Complete = true; return true; } } return true; }