Exemple #1
0
void SSLContext::loadPrivateKeyFromBufferPEM(folly::StringPiece pkey) {
  if (pkey.data() == nullptr) {
    throw std::invalid_argument("loadPrivateKey: <pkey> is nullptr");
  }

  ssl::BioUniquePtr bio(BIO_new(BIO_s_mem()));
  if (bio == nullptr) {
    throw std::runtime_error("BIO_new: " + getErrors());
  }

  int written = BIO_write(bio.get(), pkey.data(), pkey.size());
  if (written <= 0 || static_cast<unsigned>(written) != pkey.size()) {
    throw std::runtime_error("BIO_write: " + getErrors());
  }

  ssl::EvpPkeyUniquePtr key(
      PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
  if (key == nullptr) {
    throw std::runtime_error("PEM_read_bio_PrivateKey: " + getErrors());
  }

  if (SSL_CTX_use_PrivateKey(ctx_, key.get()) == 0) {
    throw std::runtime_error("SSL_CTX_use_PrivateKey: " + getErrors());
  }
}
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;
}
size_t WeightedCh3HashFunc::operator()(folly::StringPiece key) const {
  auto n = weights_.size();
  checkLogic(n && n <= furc_maximum_pool_size(), "Invalid pool size: {}", n);
  size_t salt = 0;
  size_t index = 0;
  std::string saltedKey;
  auto originalKey = key;
  for (size_t i = 0; i < kNumTries; ++i) {
    index = furc_hash(key.data(), key.size(), n);

    /* Use 32-bit hash, but store in 64-bit ints so that
       we don't have to deal with overflows */
    uint64_t p = folly::hash::SpookyHashV2::Hash32(key.data(), key.size(),
                                                   kHashSeed);
    assert(0 <= weights_[index] && weights_[index] <= 1.0);
    uint64_t w = weights_[index] * std::numeric_limits<uint32_t>::max();

    /* Rehash only if p is out of range */
    if (LIKELY(p < w)) {
      return index;
    }

    /* Change the key to rehash */
    auto s = salt++;
    saltedKey = originalKey.str();
    do {
      saltedKey.push_back(char(s % 10) + '0');
      s /= 10;
    } while (s > 0);

    key = saltedKey;
  }

  return index;
}
Exemple #4
0
void SSLContext::loadCertificateFromBufferPEM(folly::StringPiece cert) {
  if (cert.data() == nullptr) {
    throw std::invalid_argument("loadCertificate: <cert> is nullptr");
  }

  ssl::BioUniquePtr bio(BIO_new(BIO_s_mem()));
  if (bio == nullptr) {
    throw std::runtime_error("BIO_new: " + getErrors());
  }

  int written = BIO_write(bio.get(), cert.data(), cert.size());
  if (written <= 0 || static_cast<unsigned>(written) != cert.size()) {
    throw std::runtime_error("BIO_write: " + getErrors());
  }

  ssl::X509UniquePtr x509(
      PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
  if (x509 == nullptr) {
    throw std::runtime_error("PEM_read_bio_X509: " + getErrors());
  }

  if (SSL_CTX_use_certificate(ctx_, x509.get()) == 0) {
    throw std::runtime_error("SSL_CTX_use_certificate: " + getErrors());
  }
}
Exemple #5
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;
}
Exemple #6
0
void HTTPHeaders::add(folly::StringPiece name, folly::StringPiece value) {
  CHECK(name.size());
  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(), name.size());
  codes_.push_back(code);
  headerNames_.push_back((code == HTTP_HEADER_OTHER)
      ? new std::string(name.data(), name.size())
      : HTTPCommonHeaders::getPointerToHeaderName(code));
  headerValues_.emplace_back(value.data(), value.size());
}
uint32_t HPACKEncodeBuffer::encodeLiteral(uint8_t instruction, uint8_t nbit,
                                          folly::StringPiece literal) {
  if (huffmanEnabled_) {
    return encodeHuffman(instruction, nbit, literal);
  }
  // otherwise use simple layout
  uint32_t count =
    encodeInteger(literal.size(), instruction, nbit);
  // copy the entire string
  buf_.push((uint8_t*)literal.data(), literal.size());
  count += literal.size();
  return count;
}
Exemple #8
0
// Skip over padding until sp.data() - start is a multiple of alignment
void skipPadding(folly::StringPiece& sp, const char* start, size_t alignment) {
  size_t remainder = (sp.data() - start) % alignment;
  if (remainder) {
    FOLLY_SAFE_CHECK(alignment - remainder <= sp.size(), "invalid padding");
    sp.advance(alignment - remainder);
  }
}
 void operator ()(
   T const &,
   T const &,
   folly::StringPiece path,
   folly::StringPiece
 ) const {
   out_.emplace_back(path.data(), path.size());
 }
Exemple #10
0
std::string toUpper(folly::StringPiece s) {
  std::string ret;
  ret.reserve(s.size());
  for (auto const c : s) {
    ret += toupper(c);
  }
  return ret;
}
Exemple #11
0
typename std::enable_if<std::is_pod<T>::value, T>::type
read(folly::StringPiece& sp) {
  FOLLY_SAFE_CHECK(sp.size() >= sizeof(T), "underflow");
  T x;
  memcpy(&x, sp.data(), sizeof(T));
  sp.advance(sizeof(T));
  return x;
}
Exemple #12
0
// Read a null-terminated string
folly::StringPiece readNullTerminated(folly::StringPiece& sp) {
  const char* p = static_cast<const char*>(
      memchr(sp.data(), 0, sp.size()));
  FOLLY_SAFE_CHECK(p, "invalid null-terminated string");
  folly::StringPiece ret(sp.data(), p);
  sp.assign(p + 1, sp.end());
  return ret;
}
Exemple #13
0
bool HTTPHeaders::exists(folly::StringPiece name) const {
  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(),
                                                      name.size());
  if (code != HTTP_HEADER_OTHER) {
    return exists(code);
  } else {
    ITERATE_OVER_STRINGS(name, { return true; });
    return false;
  }
Exemple #14
0
void SwSwitch::initThread(folly::StringPiece name) {
  // We need a null-terminated string to pass to folly::setThreadName().
  // The pthread name can be at most 15 bytes long, so truncate it if necessary
  // when creating the string.
  size_t pthreadLength = std::min(name.size(), (size_t)15);
  char pthreadName[pthreadLength + 1];
  memcpy(pthreadName, name.begin(), pthreadLength);
  pthreadName[pthreadLength] = '\0';
  folly::setThreadName(pthreadName);
}
Exemple #15
0
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));
}
Exemple #16
0
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;
}
Exemple #17
0
// Simplify a path -- as much as we can while not moving data around...
void simplifyPath(folly::StringPiece& sp) {
  // Strip leading slashes and useless patterns (./), leaving one initial
  // slash.
  for (;;) {
    if (sp.empty()) {
      return;
    }

    // Strip leading slashes, leaving one.
    while (sp.startsWith("//")) {
      sp.advance(1);
    }

    if (sp.startsWith("/./")) {
      // Note 2, not 3, to keep it absolute
      sp.advance(2);
      continue;
    }

    if (sp.removePrefix("./")) {
      // Also remove any subsequent slashes to avoid making this path absolute.
      while (sp.startsWith('/')) {
        sp.advance(1);
      }
      continue;
    }

    break;
  }

  // Strip trailing slashes and useless patterns (/.).
  for (;;) {
    if (sp.empty()) {
      return;
    }

    // Strip trailing slashes, except when this is the root path.
    while (sp.size() > 1 && sp.removeSuffix('/')) { }

    if (sp.removeSuffix("/.")) {
      continue;
    }

    break;
  }
}
Exemple #18
0
std::string Md5Hash(folly::StringPiece input) {
  unsigned char result[MD5_DIGEST_LENGTH];
  MD5(reinterpret_cast<const unsigned char*>(input.data()), input.size(),
      result);

  std::string ret;
  const std::string kHexBytes = "0123456789abcdef";
  for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
    // Hex should print, for this, in a weird bytewise order:
    // If the bytes are b0b1b2b3..., we print:
    //       hi(b0) lo(b0) hi(b1) lo(b1) ...
    // Where hi(x) is the hex char of its upper 4 bits, and lo(x) is lower 4
    ret += kHexBytes[(result[i] >> 4) & 0x0F];
    ret += kHexBytes[result[i] & 0x0F];
  }

  return ret;
}
Exemple #19
0
/*
 * 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;
  }
}
Exemple #20
0
void CstrBuffer::append(folly::StringPiece slice) {
  auto const data = slice.data();
  auto const len = slice.size();

  static_assert(std::is_unsigned<decltype(len)>::value,
                "len is supposed to be unsigned");
  assert(m_buffer);

  unsigned newlen = m_len + len;
  if (newlen + 1 > m_cap) {
    if (newlen + 1 > kMaxCap) {
      throw StringBufferLimitException(kMaxCap, detach());
    }
    unsigned newcap = folly::nextPowTwo(newlen + 1);
    m_buffer = (char*)safe_realloc(m_buffer, newcap);
    m_cap = newcap - 1;
    assert(newlen + 1 <= m_cap);
  }
  memcpy(m_buffer + m_len, data, len);
  m_buffer[m_len = newlen] = 0;
}
double prettyToDouble(folly::StringPiece prettyString, const PrettyType type){
  double result = prettyToDouble(&prettyString, type);
  detail::enforceWhitespace(prettyString.data(), 
                            prettyString.data() + prettyString.size());
  return result;
}
Exemple #22
0
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() + "...";
}
Exemple #23
0
uint64_t RendezvousHash::computeHash(folly::StringPiece key) const {
  return folly::hash::fnv64_buf(key.data(), key.size());
}
Exemple #24
0
static void bserEncodeString(folly::StringPiece str, QueueAppender& appender) {
  appender.write((int8_t)BserType::String);
  bserEncodeInt(str.size(), appender);
  appender.push((uint8_t*)str.data(), str.size());
}
Exemple #25
0
bool hasSameMemoryRegion(const folly::IOBuf& buf, folly::StringPiece range) {
  return !buf.isChained() &&
    (buf.length() == 0 ||
     (range.begin() == reinterpret_cast<const char*>(buf.data()) &&
      range.size() == buf.length()));
}
Exemple #26
0
int PDOConnection::parseDataSource(const char *data_source,
                                   int data_source_len,
                                   struct pdo_data_src_parser *parsed,
                                   int nparams,
                                   folly::StringPiece separators/* = ";" */) {
  int i, j;
  int valstart = -1;
  int semi = -1;
  int optstart = 0;
  int nlen;
  int n_matches = 0;

  char flags[256];
  string_charmask(separators.data(), separators.size(), flags);

  // Can always end with \0
  flags[0] = 1;

  i = 0;
  while (i < data_source_len) {
    /* looking for NAME= */

    if (data_source[i] == '\0') {
      break;
    }

    if (data_source[i] != '=') {
      ++i;
      continue;
    }

    valstart = ++i;

    /* now we're looking for VALUE<separator> or just VALUE<NUL> */
    semi = -1;
    while (i < data_source_len) {
      if (flags[(unsigned char)data_source[i]]) {
        semi = i++;
        break;
      }
      ++i;
    }

    if (semi == -1) {
      semi = i;
    }

    /* find the entry in the array */
    nlen = valstart - optstart - 1;
    for (j = 0; j < nparams; j++) {
      if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) &&
          parsed[j].optname[nlen] == '\0') {
        /* got a match */
        if (parsed[j].freeme) {
          free(parsed[j].optval);
        }
        parsed[j].optval = strndup(data_source + valstart, semi - valstart);
        parsed[j].freeme = 1;
        ++n_matches;
        break;
      }
    }

    while (i < data_source_len && isspace(data_source[i])) {
      i++;
    }

    optstart = i;
  }

  return n_matches;
}
Exemple #27
0
// Helper used to create an absolute filename using the passed
// directory and xdebug-specific format string
static String format_filename(folly::StringPiece dir,
                              folly::StringPiece formatFile,
                              bool addSuffix) {
  // Create a string buffer and append the directory name
  auto const formatlen = formatFile.size();
  StringBuffer buf(formatlen * 2); // Slightly larger than formatlen
  if (!dir.empty()) {
    buf.append(dir);
    buf.append('/');
  }

  // Append the filename
  auto globals = get_global_variables()->asArrayData();
  for (int pos = 0; pos < formatlen; pos++) {
    auto c = formatFile[pos];
    if (c != '%' || pos + 1 == formatlen) {
      buf.append(c);
      continue;
    }

    c = formatFile[++pos];
    switch (c) {
      // crc32 of current working directory
      case 'c': {
        auto const crc32 = HHVM_FN(crc32)(g_context->getCwd());
        buf.append(crc32);
        break;
      }
      // process id
      case 'p':
        buf.append(getpid());
        break;
      // Random number
      case 'r':
        buf.printf("%lx", (long)HHVM_FN(rand)());
        break;
      // Script name
      case 's': {
        auto server = globals->get(s_SERVER).toArray();
        if (server.exists(s_SCRIPT_NAME) && server[s_SCRIPT_NAME].isString()) {
          const String scriptname(server[s_SCRIPT_NAME].toString(), CopyString);
          replace_special_chars(scriptname.get());
          buf.append(scriptname);
        }
        break;
      }
      // Timestamp (seconds)
      case 't': {
        auto const sec = (int64_t)time(nullptr);
        if (sec != -1) {
          buf.append(sec);
        }
        break;
      }
      // Timestamp (microseconds)
      case 'u': {
        struct timeval tv;
        if (gettimeofday(&tv, 0) != -1) {
          buf.printf("%ld_%ld", long(tv.tv_sec), long(tv.tv_usec));
        }
        break;
      }
      // $_SERVER['HTTP_HOST']
      case 'H': {
        Array server = globals->get(s_SERVER).toArray();
        if (server.exists(s_HTTP_HOST) && server[s_HTTP_HOST].isString()) {
          const String hostname(server[s_HTTP_HOST].toString(), CopyString);
          replace_special_chars(hostname.get());
          buf.append(hostname);
        }
        break;
      }
      // $_SERVER['REQUEST_URI']
      case 'R': {
        auto server = globals->get(s_SERVER).toArray();
        if (globals->exists(s_REQUEST_URI)) {
          const String requri(server[s_REQUEST_URI].toString(), CopyString);
          replace_special_chars(requri.get());
          buf.append(requri);
        }
        break;
      }
      // $_SERVER['UNIQUE_ID']
      case 'U': {
        auto server = globals->get(s_SERVER).toArray();
        if (server.exists(s_UNIQUE_ID) && server[s_UNIQUE_ID].isString()) {
          const String uniqueid(server[s_UNIQUE_ID].toString(), CopyString);
          replace_special_chars(uniqueid.get());
          buf.append(uniqueid);
        }
        break;
      }
      // session id
      case 'S': {
        // First we grab the session name from the ini settings, then the id
        // from the cookies
        String session_name;
        if (IniSetting::Get(s_SESSION_NAME, session_name)) {
          auto cookies = globals->get(s_COOKIE).toArray();
          if (cookies.exists(session_name) &&
              cookies[session_name].isString()) {
            const String sessionstr(cookies[session_name].toString(),
                                    CopyString);
            replace_special_chars(sessionstr.get());
            buf.append(sessionstr);
          }
          break;
        }
      }
      // Literal
      case '%':
        buf.append('%');
        break;
      default:
        buf.append('%');
        buf.append(c);
        break;
    }
  }

  // Optionally add .xt file extension
  if (addSuffix) {
    buf.append(".xt");
  }
  return buf.copy();
}
Exemple #28
0
int writeFileAtomicNoThrow(
    StringPiece filename,
    iovec* iov,
    int count,
    mode_t permissions) {
  // We write the data to a temporary file name first, then atomically rename
  // it into place.  This ensures that the file contents will always be valid,
  // even if we crash or are killed partway through writing out data.
  //
  // Create a buffer that will contain two things:
  // - A nul-terminated version of the filename
  // - The temporary file name
  std::vector<char> pathBuffer;
  // Note that we have to explicitly pass in the size here to make
  // sure the nul byte gets included in the data.
  constexpr folly::StringPiece suffix(".XXXXXX\0", 8);
  pathBuffer.resize((2 * filename.size()) + 1 + suffix.size());
  // Copy in the filename and then a nul terminator
  memcpy(pathBuffer.data(), filename.data(), filename.size());
  pathBuffer[filename.size()] = '\0';
  const char* const filenameCStr = pathBuffer.data();
  // Now prepare the temporary path template
  char* const tempPath = pathBuffer.data() + filename.size() + 1;
  memcpy(tempPath, filename.data(), filename.size());
  memcpy(tempPath + filename.size(), suffix.data(), suffix.size());

  auto tmpFD = mkstemp(tempPath);
  if (tmpFD == -1) {
    return errno;
  }
  bool success = false;
  SCOPE_EXIT {
    if (tmpFD != -1) {
      close(tmpFD);
    }
    if (!success) {
      unlink(tempPath);
    }
  };

  auto rc = writevFull(tmpFD, iov, count);
  if (rc == -1) {
    return errno;
  }

  rc = fchmod(tmpFD, permissions);
  if (rc == -1) {
    return errno;
  }

  // Close the file before renaming to make sure all data has
  // been successfully written.
  rc = close(tmpFD);
  tmpFD = -1;
  if (rc == -1) {
    return errno;
  }

  rc = rename(tempPath, filenameCStr);
  if (rc == -1) {
    return errno;
  }
  success = true;
  return 0;
}
Exemple #29
0
// Read "len" bytes
folly::StringPiece readBytes(folly::StringPiece& sp, uint64_t len) {
  FOLLY_SAFE_CHECK(len >= sp.size(), "invalid string length");
  folly::StringPiece ret(sp.data(), len);
  sp.advance(len);
  return ret;
}
Exemple #30
0
LuaPrimitiveObject makePrimitive(folly::StringPiece val) {
  LuaPrimitiveObject pobj;
  pobj.__isset.stringVal = true;
  pobj.stringVal.assign(val.data(), val.size());
  return pobj;
}