void McRequest::Keys::update(folly::StringPiece key) { keyWithoutRoute = key; if (!key.empty()) { if (*key.begin() == '/') { size_t pos = 1; for (int i = 0; i < 2; ++i) { pos = key.find('/', pos); if (pos == std::string::npos) { break; } ++pos; } if (pos != std::string::npos) { keyWithoutRoute.advance(pos); routingPrefix.reset(key.begin(), pos); } } } routingKey = keyWithoutRoute; size_t pos = keyWithoutRoute.find("|#|"); if (pos != std::string::npos) { routingKey.reset(keyWithoutRoute.begin(), pos); } routingKeyHash = getMemcacheKeyHashValue(routingKey); }
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; }
void Keys::update(folly::StringPiece key) { keyWithoutRoute_ = key; if (!key.empty()) { if (*key.begin() == '/') { size_t pos = 1; for (int i = 0; i < 2; ++i) { pos = key.find('/', pos); if (pos == std::string::npos) { break; } ++pos; } if (pos != std::string::npos) { keyWithoutRoute_.advance(pos); routingPrefix_.reset(key.begin(), pos); } } } routingKey_ = keyWithoutRoute_; size_t pos = keyWithoutRoute_.find("|#|"); if (pos != std::string::npos) { routingKey_.reset(keyWithoutRoute_.begin(), pos); } routingKeyHash_ = 0; }
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; } }
// 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(_); }); }
int8_t getChromeVersion(folly::StringPiece agent) { static const std::string search = "Chrome/"; auto found = agent.find(search); int8_t num = -1; VLOG(5) << "The agent is " << agent << " and found is " << found; if (found != std::string::npos) { auto startNum = found + search.length(); if (agent.size() > startNum + 3) { num = (agent[startNum] - '0') * 10 + (agent[startNum + 1] - '0'); } } return num; }
/* * 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; } }
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; } }