const std::vector<McrouterRouteHandlePtr>* RouteHandleMap::getTargetsForKeyFast(folly::StringPiece prefix, folly::StringPiece key) const { // empty prefix => route to default route if (prefix.empty()) { return &getBySingleRoute(defaultRoute_, key); } // route to all routes if (prefix == "/*/*/") { return &allRoutes_->getTargetsForKey(key); } auto starPos = prefix.find("*"); if (starPos == std::string::npos) { // no stars at all return &getBySingleRoute(prefix, key); } if (prefix.endsWith("/*/") && starPos == prefix.size() - 2) { // route to all clusters of some region (/region/*/) auto region = prefix.subpiece(1, prefix.size() - 4); auto it = byRegion_.find(region); if (it == byRegion_.end()) { return &emptyV_; } return &it->second->getTargetsForKey(key); } // no other types supported return nullptr; }
const std::vector<McrouterRouteHandlePtr>* RouteHandleMap::getTargetsForKeyFast(folly::StringPiece prefix, folly::StringPiece key) const { const std::vector<McrouterRouteHandlePtr>* result = nullptr; if (prefix.empty()) { // empty prefix => route to default route result = &defaultRouteMap_->getTargetsForKey(key); } else if (prefix == "/*/*/") { // route to all routes result = &allRoutes_->getTargetsForKey(key); } else { auto starPos = prefix.find("*"); if (starPos == std::string::npos) { // no stars at all auto it = byRoute_.find(prefix); result = it == byRoute_.end() ? &emptyV_ : &it->second->getTargetsForKey(key); } else if (prefix.endsWith("/*/") && starPos == prefix.size() - 2) { // route to all clusters of some region (/region/*/) auto region = prefix.subpiece(1, prefix.size() - 4); auto it = byRegion_.find(region); result = it == byRegion_.end() ? &emptyV_ : &it->second->getTargetsForKey(key); } } if (sendInvalidRouteToDefault_ && result != nullptr && result->empty()) { return &defaultRouteMap_->getTargetsForKey(key); } return result; }
std::shared_ptr<AccessPoint> AccessPoint::create(folly::StringPiece apString, mc_protocol_t defaultProtocol, bool defaultUseSsl, uint16_t portOverride) { if (apString.empty()) { return nullptr; } folly::StringPiece host; if (apString[0] == '[') { // IPv6 auto closing = apString.find(']'); if (closing == std::string::npos) { return nullptr; } host = apString.subpiece(1, closing - 1); apString.advance(closing + 1); } else { // IPv4 or hostname auto colon = apString.find(':'); if (colon == std::string::npos) { host = apString; apString = ""; } else { host = apString.subpiece(0, colon); apString.advance(colon); } } if (host.empty()) { return nullptr; } try { folly::StringPiece port, protocol, encr; parseParts(apString, port, protocol, encr); return std::make_shared<AccessPoint>( host, portOverride != 0 ? portOverride : folly::to<uint16_t>(port), protocol.empty() ? defaultProtocol : parseProtocol(protocol), encr.empty() ? defaultUseSsl : parseSsl(encr)); } catch (const std::exception&) { return nullptr; } }
/* * Writes a file path to a file while folding any consecutive forward slashes. */ void write_path(int fd, folly::StringPiece path) { while (!path.empty()) { auto const pos = path.find('/'); if (pos == std::string::npos) { folly::writeNoInt(fd, path.data(), path.size()); break; } auto const left = path.subpiece(0, pos + 1); folly::writeNoInt(fd, left.data(), left.size()); auto right = path.subpiece(pos); while (!right.empty() && right[0] == '/') { right = right.subpiece(1); } path = right; } }
// Helper function to check if URL has valid scheme. // http_parser only support full form scheme with double slash, // and the scheme must be all alphabetic charecter. static bool validateScheme(folly::StringPiece url) { auto schemeEnd = url.find("://"); if (schemeEnd == std::string::npos || schemeEnd == 0) { return false; } auto scheme = url.subpiece(0, schemeEnd); return std::all_of(scheme.begin(), scheme.end(), [](auto _) { return std::isalpha(_); }); }
void DebugProtocolWriter::writeSP(folly::StringPiece str) { static constexpr size_t kStringLimit = 256; static constexpr size_t kStringPrefixSize = 128; std::string toShow = str.str(); if (toShow.length() > kStringLimit) { toShow = str.subpiece(0, kStringPrefixSize).str(); folly::toAppend("[...](", str.size(), ")", &toShow); } writeItem("\"{}\"", folly::cEscape<std::string>(toShow)); }
bool getShardId(folly::StringPiece key, folly::StringPiece& shardId) { size_t colon = qfind(key, ':'); if (colon == std::string::npos) { return false; } key.advance(colon + 1); colon = qfind(key, ':'); if (colon == std::string::npos) { return false; } if (colon <= 0 || !isdigit(key[colon - 1])) { return false; } shardId = key.subpiece(0, colon); return true; }
int32_t CarbonRouterInstanceBase::getStatsEnabledPoolIndex( const folly::StringPiece poolName) const { if (statsEnabledPools_.size() == 0) { return -1; } int longestPrefixMatchIndex = -1; // Do sequential search for longest matching name. Since this is done // only once during the initialization and the size of the array is // expected to be small, linear search should be OK. for (size_t i = 0; i < statsEnabledPools_.size(); i++) { if (poolName.subpiece(0, statsEnabledPools_[i].length()) .compare(statsEnabledPools_[i]) == 0) { if ((longestPrefixMatchIndex == -1) || (statsEnabledPools_[longestPrefixMatchIndex].length() < statsEnabledPools_[i].length())) { longestPrefixMatchIndex = i; } } } return longestPrefixMatchIndex; }
std::shared_ptr<AccessPoint> AccessPoint::create( folly::StringPiece apString, mc_protocol_t defaultProtocol, SecurityMech defaultMech, uint16_t portOverride, bool defaultCompressed) { if (apString.empty()) { return nullptr; } folly::StringPiece host; bool unixDomainSocket = false; if (apString[0] == '[') { // IPv6 auto closing = apString.find(']'); if (closing == std::string::npos) { return nullptr; } host = apString.subpiece(1, closing - 1); apString.advance(closing + 1); } else { // IPv4 or hostname or UNIX domain socket if (apString.subpiece(0, 5) == "unix:") { // Unix domain socket unixDomainSocket = true; apString.advance(5); } auto colon = apString.find(':'); if (colon == std::string::npos) { host = apString; apString = ""; } else { host = apString.subpiece(0, colon); apString.advance(colon); } } if (host.empty()) { return nullptr; } try { folly::StringPiece port, protocol, encr, comp; if (unixDomainSocket) { port = "0"; parseParts(apString, protocol, encr, comp); // Unix Domain Sockets with SSL is not supported. if (!encr.empty() && parseSecurityMech(encr) != SecurityMech::NONE) { return nullptr; } } else { parseParts(apString, port, protocol, encr, comp); } return std::make_shared<AccessPoint>( host, portOverride != 0 ? portOverride : folly::to<uint16_t>(port), protocol.empty() ? defaultProtocol : parseProtocol(protocol), encr.empty() ? defaultMech : parseSecurityMech(encr), comp.empty() ? defaultCompressed : parseCompressed(comp), unixDomainSocket); } catch (const std::exception&) { return nullptr; } }
std::string shorten(folly::StringPiece s, size_t maxLength) { if (s.size() <= maxLength || s.size() <= 3) { return s.str(); } return s.subpiece(0, maxLength - 3).str() + "..."; }