const char* const content_type,
const char* const date,
const std::map<std::string, std::string>& meta_map,
+ const std::map<std::string, std::string>& qs_map,
const char* const request_uri,
const std::map<std::string, std::string>& sub_resources,
std::string& dest_str)
dest.append("\n");
dest.append(get_canon_amz_hdr(meta_map));
+ dest.append(get_canon_amz_hdr(qs_map));
dest.append(get_canon_resource(request_uri, sub_resources));
dest_str = dest;
return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
}
+static inline void get_v2_qs_map(const req_info& info,
+ std::map<std::string, std::string>& qs_map) {
+ const auto& params = const_cast<RGWHTTPArgs&>(info.args).get_params();
+ for (const auto& elt : params) {
+ std::string k = boost::algorithm::to_lower_copy(elt.first);
+ if (k.find("x-amz-meta-") == /* offset */ 0) {
+ add_amz_meta_header(qs_map, k, elt.second);
+ }
+ }
+}
+
/*
* get the header authentication information required to
* compute a request's signature
const char *content_type = info.env->get("CONTENT_TYPE");
std::string date;
+ std::map<std::string, std::string> qs_map;
+
if (qsr) {
+ get_v2_qs_map(info, qs_map); // handle qs metadata
date = info.args.get("Expires");
} else {
const char *str = info.env->get("HTTP_X_AMZ_DATE");
}
rgw_create_s3_canonical_header(info.method, content_md5, content_type,
- date.c_str(), meta_map, request_uri.c_str(),
- sub_resources, dest);
+ date.c_str(), meta_map, qs_map,
+ request_uri.c_str(), sub_resources, dest);
return true;
}
const char *content_type,
const char *date,
const std::map<std::string, std::string>& meta_map,
+ const std::map<std::string, std::string>& qs_map,
const char *request_uri,
const std::map<std::string, std::string>& sub_resources,
std::string& dest_str);
#include <algorithm>
#include <string>
#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/utility/string_view.hpp>
#include "json_spirit/json_spirit.h"
#include "common/ceph_json.h"
STR_LEN_ENTRY("HTTP_X_ACCOUNT"),
{NULL, 0} };
-
void req_info::init_meta_info(bool *found_bad_meta)
{
x_meta_map.clear();
#include <array>
+#include <boost/algorithm/string.hpp>
#include <boost/utility/string_view.hpp>
#include "common/ceph_crypto.h"
return ((bytes + 4095) & ~4095) / 1024;
}
+/* implement combining step, S3 header canonicalization; k is a
+ * valid header and in lc form */
+static inline void add_amz_meta_header(
+ std::map<std::string, std::string>& x_meta_map,
+ const std::string& k,
+ const std::string& v)
+{
+ auto it = x_meta_map.find(k);
+ if (it != x_meta_map.end()) {
+ std::string old = it->second;
+ boost::algorithm::trim_right(old);
+ old.append(",");
+ old.append(v);
+ x_meta_map[k] = old;
+ } else {
+ x_meta_map[k] = v;
+ }
+} /* add_amz_meta_header */
+
extern string rgw_string_unquote(const string& s);
extern void parse_csv_string(const string& ival, vector<string>& ovals);
extern int parse_key_value(string& in_str, string& key, string& val);
content_type.c_str(),
date_str.c_str(),
meta_map,
+ map<string, string>{},
uri.c_str(),
sub_resources,
canonical_header);
string canonical_header;
map<string, string> meta_map;
map<string, string> sub_resources;
+
rgw_create_s3_canonical_header(method.c_str(), NULL, NULL, date_str.c_str(),
- meta_map, url.c_str(), sub_resources,
- canonical_header);
+ meta_map, meta_map, url.c_str(), sub_resources,
+ canonical_header);
string digest;
try {
}
}
+static inline void map_qs_metadata(struct req_state* s)
+{
+ /* merge S3 valid user metadata from the query-string into
+ * x_meta_map, which maps them to attributes */
+ const auto& params = const_cast<RGWHTTPArgs&>(s->info.args).get_params();
+ for (const auto& elt : params) {
+ std::string k = boost::algorithm::to_lower_copy(elt.first);
+ if (k.find("x-amz-meta-") == /* offset */ 0) {
+ add_amz_meta_header(s->info.x_meta_map, k, elt.second);
+ }
+ }
+}
+
int RGWPutObj_ObjStore_S3::get_params()
{
if (!s->length)
size_t pos;
int ret;
+ map_qs_metadata(s);
+
RGWAccessControlPolicy_S3 s3policy(s->cct);
ret = create_s3_policy(s, store, s3policy, s->owner);
if (ret < 0)
return op_ret;
}
+ map_qs_metadata(s);
+
ldout(s->cct, 20) << "adding bucket to policy env: " << s->bucket.name
<< dendl;
env.add_var("bucket", s->bucket.name);
return ret;
}
+ map_qs_metadata(s);
+
return do_aws4_auth_completion();
}