diff options
-rw-r--r-- | src/rgw/rgw_rest_client.cc | 62 | ||||
-rw-r--r-- | src/rgw/rgw_rest_client.h | 13 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 4 |
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 = \ |