Пример #1
0
rc_t names_request ( const request_params * request, bool cache, bool path ) {
    rc_t rc = 0;

    KService * service = NULL;

    VRemoteProtocols protocols = 0;

    assert ( request && request -> terms );

    if ( sizeof PROTOCOLS / sizeof PROTOCOLS [ 0 ] != eProtocolMax ) {
        rc = RC ( rcExe, rcTable, rcValidating, rcTable, rcIncomplete );
        LOGERR ( klogFatal, rc, "Incomplete PROTOCOLS array" );
        assert ( sizeof PROTOCOLS / sizeof PROTOCOLS [ 0 ] == eProtocolMax );
        return rc;
    }

    if ( request -> params != NULL && * request -> params != NULL )
        LOGMSG ( klogWarn, "'--" OPTION_PARAM "' is ignored: "
            "it used just with '--" OPTION_RAW "' '" FUNCTION_NAMES "' and '"
            FUNCTION_SEARCH "' funtions") ;

    rc = KService_Make ( & service, request );

    if ( rc == 0 ) {
        if ( rc == 0 && request -> projects != NULL &&
             request -> projects [ 0 ] != 0 )
        {
            uint32_t * ptr = NULL;
            for ( ptr = request -> projects; * ptr != 0; ++ ptr ) {
                rc = KServiceAddProject ( service, * ptr );
                if ( rc != 0 ) {
                    PLOGERR ( klogErr, ( klogErr, rc,
                        "Cannot add project '$(p)'", "p=%u", * ptr ) );
                    break;
                }
            }
        }
    }

    if ( rc == 0 && request -> proto != NULL )
        protocols = parseProtocol ( request -> proto, & rc );

    if ( rc == 0 ) {
        if ( cache )
            rc = names_remote_cache ( service, protocols, request, path );
        else
            rc = names_remote       ( service, protocols, request, path );
    }

    RELEASE ( KService, service );

    return rc;
}
Пример #2
0
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;
    }
}
Пример #3
0
result_t Url::parse(exlib::string url, bool parseQueryString, bool slashesDenoteHost)
{
    bool bHost;
    clear();
    m_slashes = false;

    trimUrl(url, url);
    const char* c_str = url.c_str();
    bool hasHash = qstrchr(c_str, '#') != NULL;

    if (!slashesDenoteHost && !hasHash && isUrlSlash(*c_str)) {
        parsePath(c_str);
        parseQuery(c_str);
        parseHash(c_str);

        if (parseQueryString) {
            m_queryParsed = new HttpCollection();
            m_queryParsed->parse(m_query);
        }

        return 0;
    }

    parseProtocol(c_str);

    bHost = checkHost(c_str);

    if (slashesDenoteHost || m_protocol.length() > 0 || bHost)
        m_slashes = ((isUrlSlash(*c_str) && isUrlSlash(c_str[1])) && (m_protocol.length() <= 0 || m_protocol.compare("javascript:")));

    if (m_protocol.compare("javascript:") && m_slashes) {
        c_str += 2;
        parseAuth(c_str);
        parseHost(c_str);
    }

    parsePath(c_str);
    parseQuery(c_str);
    parseHash(c_str);

    if (parseQueryString) {
        m_queryParsed = new HttpCollection();
        m_queryParsed->parse(m_query);
    }

    return 0;
}
Пример #4
0
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;
  }
}
Пример #5
0
int HttpRequest::parseFirstLine( const CircularBuffer &buf ) {
   TRACE_BEGIN( LOG_LVL_INFO );

   std::string method;
   method.reserve( MAX_METHOD_SIZE );
   std::string uri;
   uri.reserve( MAX_URI_SIZE );
   std::string protocol;
   protocol.reserve( MAX_PROTO_SIZE );
   int i = 0;
   int c;

   while (1) {
      c = buf.byteAt( i++ );

      // If we requested a byte beyond the line size . . .
      if ( c == -1 or i > buf.getLength() ) {
         return -1;
      }

      if ( c == ' ' ) {
         break;
      }

      method += c;
      if ( method.size() >= MAX_METHOD_SIZE )
         return -1;
   }

   while (( c = buf.byteAt( i ) == ' ' )) {
      i++;

      // If we requested a byte beyond the line size . . .
      if ( c == -1 or i > buf.getLength() ) {
         return -1;
      }
   }

   while (1) {
      c = buf.byteAt( i++ );

      // If we requested a byte beyond the line size . . .
      if ( c == -1 or i > buf.getLength() ) {
         return -1;
      }

      if ( c == ' ' )
         break;

      uri += c;
      if ( uri.size() >= MAX_URI_SIZE )
         return -1;
   }

   while (1) {
      c = buf.byteAt( i++ );

      // If we requested a byte beyond the line size . . .
      if ( c == -1 or i > buf.getLength() ) {
         return -1;
      }

      if ( c == '\r' )
         break;

      protocol += c;
      if ( protocol.size() >= MAX_PROTO_SIZE )
         return -1;
   }

   // if CRLF move past LF
   if ( buf.byteAt( i ) == '\n' )
      i++;

   LOG( "Method %s, URI %s, Proto %s",
         method.c_str(), uri.c_str(), protocol.c_str() );

   parseProtocol( protocol.c_str() );
   parseMethod( method.c_str() );
   mUri = uri.c_str();

   return i;
}
Пример #6
0
std::shared_ptr<ClientPool>
PoolFactory::parsePool(const std::string& name, const folly::dynamic& json) {
  auto seenPoolIt = pools_.find(name);
  if (seenPoolIt != pools_.end()) {
    return seenPoolIt->second;
  }

  if (json.isString()) {
    // get the pool from ConfigApi
    std::string jsonStr;
    checkLogic(configApi_.get(ConfigType::Pool, name, jsonStr),
               "Can not read pool: {}", name);
    return parsePool(name, parseJsonString(jsonStr));
  } else {
    // one day we may add inheriting from local pool
    if (auto jinherit = json.get_ptr("inherit")) {
      checkLogic(jinherit->isString(),
                 "Pool {}: inherit is not a string", name);
      auto path = jinherit->stringPiece().str();
      std::string jsonStr;
      checkLogic(configApi_.get(ConfigType::Pool, path, jsonStr),
                 "Can not read pool from: {}", path);
      auto newJson = parseJsonString(jsonStr);
      for (auto& it : json.items()) {
        newJson.insert(it.first, it.second);
      }
      newJson.erase("inherit");
      return parsePool(name, newJson);
    }
  }

  // pool_locality
  std::chrono::milliseconds timeout{opts_.server_timeout_ms};
  if (auto jlocality = json.get_ptr("pool_locality")) {
    if (!jlocality->isString()) {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "Pool {}: pool_locality is not a string", name);
    } else {
      auto str = jlocality->stringPiece();
      if (str == "cluster") {
        if (opts_.cluster_pools_timeout_ms != 0) {
          timeout = std::chrono::milliseconds(opts_.cluster_pools_timeout_ms);
        }
      } else if (str == "region") {
        if (opts_.regional_pools_timeout_ms != 0) {
          timeout = std::chrono::milliseconds(opts_.regional_pools_timeout_ms);
        }
      } else {
        MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                       "Pool {}: '{}' pool locality is not supported",
                       name, str);
      }
    }
  }

  // region & cluster
  std::string region, cluster;
  if (auto jregion = json.get_ptr("region")) {
    if (!jregion->isString()) {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "Pool {}: pool_region is not a string", name);
    } else {
      region = jregion->stringPiece().str();
    }
  }
  if (auto jcluster = json.get_ptr("cluster")) {
    if (!jcluster->isString()) {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "Pool {}: pool_cluster is not a string", name);
    } else {
      cluster = jcluster->stringPiece().str();
    }
  }

  if (auto jtimeout = json.get_ptr("server_timeout")) {
    if (!jtimeout->isInt()) {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "Pool {}: server_timeout is not an int", name);
    } else {
      timeout = std::chrono::milliseconds(jtimeout->getInt());
    }
  }

  if (!region.empty() && !cluster.empty()) {
    auto& route = opts_.default_route;
    if (region == route.getRegion() && cluster == route.getCluster()) {
      if (opts_.within_cluster_timeout_ms != 0) {
        timeout = std::chrono::milliseconds(opts_.within_cluster_timeout_ms);
      }
    } else if (region == route.getRegion()) {
      if (opts_.cross_cluster_timeout_ms != 0) {
        timeout = std::chrono::milliseconds(opts_.cross_cluster_timeout_ms);
      }
    } else {
      if (opts_.cross_region_timeout_ms != 0) {
        timeout = std::chrono::milliseconds(opts_.cross_region_timeout_ms);
      }
    }
  }

  auto protocol = parseProtocol(json, mc_ascii_protocol);

  bool keep_routing_prefix = false;
  if (auto jkeep_routing_prefix = json.get_ptr("keep_routing_prefix")) {
    checkLogic(jkeep_routing_prefix->isBool(),
               "Pool {}: keep_routing_prefix is not a bool");
    keep_routing_prefix = jkeep_routing_prefix->getBool();
  }

  uint64_t qosClass = opts_.default_qos_class;
  uint64_t qosPath = opts_.default_qos_path;
  if (auto jqos = json.get_ptr("qos")) {
    parseQos(folly::sformat("Pool {}", name), *jqos, qosClass, qosPath);
  }

  bool useSsl = false;
  if (auto juseSsl = json.get_ptr("use_ssl")) {
    checkLogic(juseSsl->isBool(), "Pool {}: use_ssl is not a bool", name);
    useSsl = juseSsl->getBool();
  }

  // servers
  auto jservers = json.get_ptr("servers");
  checkLogic(jservers, "Pool {}: servers not found", name);
  checkLogic(jservers->isArray(), "Pool {}: servers is not an array", name);
  auto clientPool = std::make_shared<ClientPool>(name);
  for (size_t i = 0; i < jservers->size(); ++i) {
    const auto& server = jservers->at(i);
    std::shared_ptr<AccessPoint> ap;
    bool serverUseSsl = useSsl;
    uint64_t serverQosClass = qosClass;
    uint64_t serverQosPath = qosPath;
    checkLogic(server.isString() || server.isObject(),
               "Pool {}: server #{} is not a string/object", name, i);
    if (server.isString()) {
      // we support both host:port and host:port:protocol
      ap = AccessPoint::create(server.stringPiece(), protocol);
      checkLogic(ap != nullptr,
                 "Pool {}: invalid server {}", name, server.stringPiece());
    } else { // object
      auto jhostname = server.get_ptr("hostname");
      checkLogic(jhostname,
                 "Pool {}: hostname not found for server #{}", name, i);
      checkLogic(jhostname->isString(),
                 "Pool {}: hostname is not a string for server #{}", name, i);

      if (auto jqos = server.get_ptr("qos")) {
        parseQos(folly::sformat("Pool {}, server #{}", name, i),
                 *jqos, qosClass, qosPath);
      }

      if (auto juseSsl = server.get_ptr("use_ssl")) {
        checkLogic(juseSsl->isBool(),
                   "Pool {}: use_ssl is not a bool for server #{}", name, i);
        serverUseSsl = juseSsl->getBool();
      }

      ap = AccessPoint::create(jhostname->stringPiece(),
                               parseProtocol(server, protocol));
      checkLogic(ap != nullptr, "Pool {}: invalid server #{}", name, i);
    }

    auto client = clientPool->emplaceClient(
      timeout,
      std::move(ap),
      keep_routing_prefix,
      serverUseSsl,
      serverQosClass,
      serverQosPath);

    clients_.push_back(std::move(client));
  } // servers

  // weights
  if (auto jweights = json.get_ptr("weights")) {
    clientPool->setWeights(*jweights);
  }

  pools_.emplace(name, clientPool);
  return clientPool;
}
Пример #7
0
void PackageParser::parse() {
    while (stream_.hasMoreTokens()) {
        auto documentation = parseDocumentationToken();
        
        auto exported = Attribute<E_EARTH_GLOBE_EUROPE_AFRICA>().parse(&stream_);
        auto theToken = stream_.consumeToken(IDENTIFIER);
        switch (theToken.value[0]) {
            case E_PACKAGE: {
                exported.disallow();
                
                auto nameToken = stream_.consumeToken(VARIABLE);
                auto namespaceToken = stream_.consumeToken(IDENTIFIER);
                
                auto name = nameToken.value.utf8CString();
                package_->loadPackage(name, namespaceToken.value[0], theToken);
                
                continue;
            }
            case E_CROCODILE:
                parseProtocol(documentation, theToken, exported.set());
                continue;
            case E_TURKEY:
                parseEnum(documentation, exported.set());
                continue;
            case E_RADIO:
                exported.disallow();
                package_->setRequiresBinary();
                if (strcmp(package_->name(), "_") == 0) {
                    throw CompilerErrorException(theToken, "You may not set 📻 for the _ package.");
                }
                continue;
            case E_CRYSTAL_BALL: {
                exported.disallow();
                if (package_->validVersion()) {
                    throw CompilerErrorException(theToken, "Package version already declared.");
                }
                
                auto major = stream_.consumeToken(INTEGER).value.utf8CString();
                auto minor = stream_.consumeToken(INTEGER).value.utf8CString();
                
                uint16_t majori = strtol(major, nullptr, 0);
                uint16_t minori = strtol(minor, nullptr, 0);
                
                delete [] major;
                delete [] minor;
                
                package_->setPackageVersion(PackageVersion(majori, minori));
                if (!package_->validVersion()) {
                    throw CompilerErrorException(theToken, "The provided package version is not valid.");
                }
                
                continue;
            }
            case E_WALE: {
                exported.disallow();
                EmojicodeChar className, enamespace;
                bool optional;
                auto &classNameToken = parseTypeName(&className, &enamespace, &optional);
                
                if (optional) {
                    throw CompilerErrorException(classNameToken, "Optional types are not extendable.");
                }
                
                Type type = typeNothingness;
                
                if (!package_->fetchRawType(className, enamespace, optional, theToken, &type)) {
                    throw CompilerErrorException(classNameToken, "Class does not exist.");
                }
                if (type.type() != TT_CLASS) {
                    throw CompilerErrorException(classNameToken, "Only classes are extendable.");
                }
                
                // Native extensions are allowed if the class was defined in this package.
                parseClassBody(type.eclass, nullptr, type.eclass->package() == package_);
                
                continue;
            }
            case E_RABBIT:
                parseClass(documentation, theToken, exported.set());
                continue;
            case E_SCROLL: {
                exported.disallow();
                auto pathString = stream_.consumeToken(STRING);
                auto relativePath = pathString.position().file;
                auto fileString = pathString.value.utf8CString();
                
                char *str = fileString;
                const char *lastSlash = strrchr(relativePath, '/');
                if (lastSlash != nullptr) {
                    const char *directory = strndup(relativePath, lastSlash - relativePath);
                    asprintf(&str, "%s/%s", directory, fileString);
                    delete [] fileString;
                    delete [] directory;
                }
                
                PackageParser(package_, lex(str)).parse();
                
                delete [] str;
                continue;
            }
            default:
                ecCharToCharStack(theToken.value[0], f);
                throw CompilerErrorException(theToken, "Unexpected identifier %s", f);
                break;
        }
    }
}