예제 #1
0
bool SPDYUtil::hasGzipAndDeflate(const std::string& value, bool& hasGzip,
                                 bool& hasDeflate) {
  static folly::ThreadLocal<std::vector<RFC2616::TokenQPair>> output;
  output->clear();
  hasGzip = false;
  hasDeflate = false;
  RFC2616::parseQvalues(value, *output);
  for (const auto& encodingQ: *output) {
    std::string lower(encodingQ.first.str());
    std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
    // RFC says 3 sig figs
    if (lower == "gzip" && encodingQ.second >= 0.001) {
      hasGzip = true;
    } else if (lower == "deflate" && encodingQ.second >= 0.001) {
      hasDeflate = true;
    }
  }
  return hasGzip && hasDeflate;
}
예제 #2
0
bool parseQvalues(folly::StringPiece value, std::vector<TokenQPair> &output) {
  bool result = true;
  static folly::ThreadLocal<std::vector<folly::StringPiece>> tokens;
  tokens->clear();
  folly::split(",", value, *tokens, true /*ignore empty*/);
  for (auto& token: *tokens) {
    auto pos = token.find(';');
    double qvalue = 1.0;
    if (pos != std::string::npos) {
      auto qpos = token.find("q=", pos);
      if (qpos != std::string::npos) {
        folly::StringPiece qvalueStr(token.data() + qpos + 2,
                                     token.size() - (qpos + 2));
        try {
          qvalue = folly::to<double>(&qvalueStr);
        } catch (const std::range_error&) {
          // q=<some garbage>
          result = false;
        }
        // we could validate that the remainder of qvalueStr was all whitespace,
        // for now we just discard it
      } else {
        // ; but no q=
        result = false;
      }
      token.reset(token.start(), pos);
    }
    // strip leading whitespace
    while (token.size() > 0 && isspace(token[0])) {
      token.reset(token.start() + 1, token.size() - 1);
    }
    if (token.size() == 0) {
      // empty token
      result = false;
    } else {
      output.emplace_back(token, qvalue);
    }
  }
  return result && output.size() > 0;
}