SimpleTemplate::SimpleTemplate(boost::string_ref text) { static char const rawMarker[] = "@@"; static boost::string_ref const marker(rawMarker, sizeof(rawMarker) - 1); auto beg = text.find(marker); while (beg != boost::string_ref::npos) { m_literals.emplace_back(text.data(), beg); text.remove_prefix(beg + marker.size()); auto end = text.find(marker); if (end == boost::string_ref::npos) { std::string& lit = m_literals.back(); lit.reserve(lit.size() + marker.size() + text.size()); lit.append(marker.data(), marker.size()); lit.append(text.data(), text.size()); assert(m_literals.size() == m_insertionKeys.size() + 1); return; } m_insertionKeys.emplace_back(text.data(), end); text.remove_prefix(end + marker.size()); beg = text.find(marker); } m_literals.emplace_back(text.data(), text.size()); assert(m_literals.size() == m_insertionKeys.size() + 1); }
std::string CHttpUrl::ParseDomain(boost::string_ref & url) { auto domainPos = url.find(':'); if (domainPos == boost::string_ref::npos) { domainPos = url.find("/"); domainPos = (domainPos == boost::string_ref::npos ? url.size() : domainPos); } auto domain = url.substr(0, domainPos).to_string(); url = url.substr(domainPos, url.size()); return domain; }
Protocol CHttpUrl::CheckProtocol(boost::string_ref const &url, size_t &index) { Protocol protocol; auto pos = url.find("://"); if (pos != url.size()) { if (url.substr(0, pos) == "https") { protocol = Protocol::HTTPS; } else if (url.substr(0, pos) == "http") { protocol = Protocol::HTTP; } else { throw std::invalid_argument("Protocol uncorrect."); } if (index == url.size()) { throw std::invalid_argument("Invalid url was introduced"); } } index = pos + 3; return protocol; }
unsigned short CHttpUrl::ParsePort(boost::string_ref & str) { if (str.front() == ':') { auto portPos = str.find('/'); string port; if (portPos == boost::string_ref::npos) { port = str.substr(1, str.size()).to_string(); } else { port = str.substr(1, portPos - 1).to_string(); } str = str.substr(port.size() + 1, str.size()); bool portOk = !port.empty(); if (portOk) { try { return boost::lexical_cast<unsigned short>(port); } catch (...) { portOk = false; } } if (!portOk) { throw CUrlParsingError("Port parsing error"); } } return 0; }
Protocol CHttpUrl::ParseProtocol(boost::string_ref & str) { const string schemeDelimiter = "://"; auto schemePos = str.find(schemeDelimiter); if (schemePos == boost::string_ref::npos) { throw CUrlParsingError("Protocol parsing error"); } string protocol = str.substr(0, schemePos).to_string(); str = str.substr(schemePos + schemeDelimiter.size() , str.size() - 1); return ToProtocol(protocol); }
bool HttpAbpBaseFilter::IsMatch(boost::string_ref data, const HttpAbpFilterSettings dataSettings, boost::string_ref dataHost) const { if (!SettingsApply(dataSettings, m_settings)) { return false; } size_t i = 0; auto len = m_ruleParts.size(); size_t lastMatch = 0; for (i = 0; i < m_ruleParts.size(); ++i) { switch (m_rulePartTypes[i]) { // Anchored address matching is basically a confusing way to say that we // must match against the host of the request, AFAIK. // // However, we have a double wammy. If we match against the host, we // need to then find that same matched string in the full request and // substring the data from beyond our matched address string. This is a // PITA and a bit of a waste, but we check the dataHost member first // specifically, to avoid false positives, such as Google search results // that embed a URL we're trying to match against in GET parameters. case RulePartType::AnchoredAddress: { auto hostLen = dataHost.size(); auto plen = m_ruleParts[i].size(); if (plen <= hostLen) { auto res = dataHost.find(m_ruleParts[i]); if (res != boost::string_ref::npos) { auto hostInReqPos = data.find(dataHost); if (hostInReqPos != boost::string_ref::npos) { lastMatch = hostInReqPos + res + plen; continue; } } } return false; } break; case RulePartType::Wildcard: { // Wildcard, so as long as we have one additional character, we can move on. if (lastMatch + 1 <= data.size()) { ++lastMatch; continue; } return false; } break; case RulePartType::Separator: { if (lastMatch < data.size()) { data = data.substr(lastMatch); auto sepPosition = data.find_first_of(SeparatorStrRef); if (sepPosition != boost::string_ref::npos) { lastMatch = sepPosition + 1; continue; } } return false; } break; case RulePartType::StringLiteral: { if (lastMatch < data.size()) { data = data.substr(lastMatch); size_t literalTextPosition = data.find(m_ruleParts[i]); if(literalTextPosition != boost::string_ref::npos) { lastMatch = literalTextPosition + m_ruleParts[i].size(); continue; } } return false; } break; // Must be an exact match. case RulePartType::RequestLiteralMatch: { return util::string::Equal(data, m_ruleParts[i]); } break; // Basically just a substring match against the start of the request. case RulePartType::RequestLiteralPartialMatch: { auto plen = m_ruleParts[i].size(); auto reqSize = data.size(); if (plen <= reqSize) { auto sub = data.substr(0, plen); if (util::string::Equal(m_ruleParts[i], sub)) { lastMatch = plen; continue; } } return false; } break; } } // All matches were found successfully so, we matched return true; }