string signature_v2()

in util/cpp/src/ossutil.cpp [680:757]


string signature_v2(Darabonba::Request req, string bucketName, string secret, vector<string> addtionalHeaders) {
  string resource;
  string pathname;
  if (bucketName.empty()) {
    pathname = req.pathname;
  } else {
    pathname = "/" + bucketName + req.pathname;
  };

  vector<string> query_sorted_keys;
  for (const auto& i : req.query) {
    query_sorted_keys.push_back(i.first);
  }

  vector<string> strs;
  boost::split(strs, pathname, boost::is_any_of("?"));
  resource += url_encode(strs[0]);

  if (regex_search(pathname, regex("\\?"))) {
    query_sorted_keys.push_back(strs[1]);
  }

  sort(query_sorted_keys.begin(), query_sorted_keys.end());
  if (!query_sorted_keys.empty()) {
    resource += "?";
  }

  for (const auto& key : query_sorted_keys) {
    if (req.query.find(key) != req.query.end()) {
      if (boost::ends_with(resource, "?")) {
        resource += url_encode(key) + "=" + url_encode(req.query.at(key));
      } else {
        resource += "&" + url_encode(key) + "=" + url_encode(req.query.at(key));
      }
    } else {
      if (boost::ends_with(resource, "?")) {
        resource += url_encode(key);
      } else {
        resource += "&" + url_encode(key);
      }
    }
  }

  vector<string> header_sorted_keys;
  map<string, string> tmp;
  for (auto i : req.headers) {
    string key = boost::algorithm::to_lower_copy(i.first);
    if (boost::starts_with(key, "x-oss-")) {
      tmp[key] = i.second;
      header_sorted_keys.push_back(key);
    }
  }
  sort(header_sorted_keys.begin(), header_sorted_keys.end());

  string can_oss_headers;
  for (const auto& key : header_sorted_keys) {
    can_oss_headers += key + ":" + tmp.at(key) + "\n";
  }

  string date;
  string content_type;
  string content_md5;
  if (req.headers.find("date") != req.headers.end()) {
    date = req.headers.at("date");
  }
  if (req.headers.find("content-type") != req.headers.end()) {
    content_type = req.headers.at("content-type");
  }
  if (req.headers.find("content-md5") != req.headers.end()) {
    content_md5 = req.headers.at("content-md5");
  }

  string sign_str = req.method + "\n" + content_md5 + "\n" + content_type + "\n" + date + "\n" + can_oss_headers + boost::join(addtionalHeaders, ";") + "\n" + resource;

  boost::uint8_t hash_val[sha256::HASH_SIZE];
  hmac<sha256>::calc(sign_str, secret, hash_val);
  return base64::encode_from_array(hash_val, sha256::HASH_SIZE);
}