summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/rgw/rgw_rest_client.cc62
-rw-r--r--src/rgw/rgw_rest_client.h13
-rw-r--r--src/rgw/rgw_rest_s3.cc4
3 files changed, 51 insertions, 28 deletions
diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc
index 5303b9c37a0..1918adbc800 100644
--- a/src/rgw/rgw_rest_client.cc
+++ b/src/rgw/rgw_rest_client.cc
@@ -548,11 +548,6 @@ int RGWRESTGenerateHTTPHeaders::set_obj_attrs(map<string, bufferlist>& rgw_attrs
return 0;
}
-static std::set<string> keep_headers = { "content-type",
- "content-encoding",
- "content-disposition",
- "content-language" };
-
void RGWRESTGenerateHTTPHeaders::set_http_attrs(const map<string, string>& http_attrs)
{
/* merge send headers */
@@ -585,6 +580,16 @@ void RGWRESTGenerateHTTPHeaders::set_policy(RGWAccessControlPolicy& policy)
add_grants_headers(grants_by_type, *new_env, new_info->x_meta_map);
}
+void RGWRESTGenerateHTTPHeaders::set_content(const bufferlist& bl)
+{
+ static string attr("HTTP_X_AMZ_CONTENT_SHA256");
+
+ string hash = (bl.length() == 0 ? string(rgw::auth::s3::AWS4_EMPTY_PAYLOAD_HASH) :
+ rgw::auth::s3::calc_v4_payload_hash(bl.to_str()));
+ new_env->set(attr, hash);
+ new_info->x_meta_map["x-amz-content-sha256"] = hash;
+}
+
int RGWRESTGenerateHTTPHeaders::sign(RGWAccessKey& key)
{
int ret = sign_request(this, key, region, *new_env, *new_info);
@@ -741,9 +746,6 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
if (new_url[new_url.size() - 1] != '/')
new_url.append("/");
- RGWEnv new_env;
- req_info new_info(cct, &new_env);
-
string new_resource;
string bucket_name;
string old_resource = resource;
@@ -771,26 +773,14 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
}
}
- RGWRESTGenerateHTTPHeaders headers_gen(cct, &new_env, &new_info);
+ headers_gen.emplace(cct, &new_env, &new_info);
- headers_gen.init(method, host, resource_prefix, new_url, new_resource, params, api_name);
+ headers_gen->init(method, host, resource_prefix, new_url, new_resource, params, api_name);
- headers_gen.set_http_attrs(extra_headers);
+ headers_gen->set_http_attrs(extra_headers);
if (key) {
-#if 0
- new_info.init_meta_info(nullptr);
-#endif
-
- int ret = headers_gen.sign(*key);
- if (ret < 0) {
- ldout(cct, 0) << "ERROR: failed to sign request" << dendl;
- return ret;
- }
- }
-
- for (const auto& kv: new_env.get_map()) {
- headers.emplace_back(kv);
+ sign_key = *key;
}
if (send_data) {
@@ -798,10 +788,9 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
set_outbl(*send_data);
set_send_data_hint(true);
}
-
method = new_info.method;
- url = headers_gen.get_url();
+ url = headers_gen->get_url();
return 0;
}
@@ -820,6 +809,27 @@ int RGWRESTStreamRWRequest::send_request(RGWAccessKey *key, map<string, string>&
int RGWRESTStreamRWRequest::send(RGWHTTPManager *mgr)
{
+ if (!headers_gen) {
+ ldout(cct, 0) << "ERROR: " << __func__ << "(): send_prepare() was not called: likey a bug!" << dendl;
+ return -EINVAL;
+ }
+
+ if (send_len == outbl.length()) {
+ headers_gen->set_content(outbl);
+ }
+
+ if (sign_key) {
+ int r = headers_gen->sign(*sign_key);
+ if (r < 0) {
+ ldout(cct, 0) << "ERROR: failed to sign request" << dendl;
+ return r;
+ }
+ }
+
+ for (const auto& kv: new_env.get_map()) {
+ headers.emplace_back(kv);
+ }
+
if (!mgr) {
return RGWHTTP::send(this);
}
diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h
index 08a2f75da00..03b12a730ff 100644
--- a/src/rgw/rgw_rest_client.h
+++ b/src/rgw/rgw_rest_client.h
@@ -94,6 +94,7 @@ public:
int set_obj_attrs(map<string, bufferlist>& rgw_attrs);
void set_http_attrs(const map<string, string>& http_attrs);
void set_policy(RGWAccessControlPolicy& policy);
+ void set_content(const bufferlist& bl);
int sign(RGWAccessKey& key);
const string& get_url() { return url; }
@@ -110,7 +111,6 @@ private:
ceph::make_mutex("RGWHTTPStreamRWRequest::write_lock");
ReceiveCB *cb{nullptr};
RGWWriteDrainCB *write_drain_cb{nullptr};
- bufferlist outbl;
bufferlist in_data;
size_t chunk_ofs{0};
size_t ofs{0};
@@ -120,6 +120,8 @@ private:
bool stream_writes{false};
bool write_stream_complete{false};
protected:
+ bufferlist outbl;
+
int handle_header(const string& name, const string& val) override;
public:
int send_data(void *ptr, size_t len, bool *pause) override;
@@ -173,6 +175,11 @@ public:
};
class RGWRESTStreamRWRequest : public RGWHTTPStreamRWRequest {
+ std::optional<RGWAccessKey> sign_key;
+ std::optional<RGWRESTGenerateHTTPHeaders> headers_gen;
+ RGWEnv new_env;
+ req_info new_info;
+
protected:
std::optional<string> api_name;
HostStyle host_style;
@@ -180,7 +187,9 @@ public:
RGWRESTStreamRWRequest(CephContext *_cct, const string& _method, const string& _url, RGWHTTPStreamRWRequest::ReceiveCB *_cb,
param_vec_t *_headers, param_vec_t *_params,
std::optional<std::string> _api_name, HostStyle _host_style = PathStyle) :
- RGWHTTPStreamRWRequest(_cct, _method, _url, _cb, _headers, _params), api_name(_api_name), host_style(_host_style) {
+ RGWHTTPStreamRWRequest(_cct, _method, _url, _cb, _headers, _params),
+ new_info(_cct, &new_env),
+ api_name(_api_name), host_style(_host_style) {
}
virtual ~RGWRESTStreamRWRequest() override {}
diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc
index 7b5a3e937b7..2b9ca215935 100644
--- a/src/rgw/rgw_rest_s3.cc
+++ b/src/rgw/rgw_rest_s3.cc
@@ -5217,6 +5217,10 @@ AWSSignerV4::prepare(const std::string& access_key_id,
std::string credential_scope = gen_v4_scope(timestamp, region);
extra_headers["x-amz-date"] = date;
+ auto iter = info.x_meta_map.find("x-amz-content-sha256");
+ if (iter != info.x_meta_map.end()) {
+ extra_headers[iter->first] = iter->second;
+ }
/* craft canonical headers */
std::string canonical_headers = \