1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #include "rgw_http_client.h"
10 class RGWHTTPSimpleRequest
: public RGWHTTPClient
{
15 using unique_lock
= std::unique_lock
<std::mutex
>;
17 std::mutex out_headers_lock
;
18 std::map
<std::string
, std::string
> out_headers
;
21 bufferlist::iterator
*send_iter
;
23 size_t max_response
; /* we need this as we don't stream out response */
26 virtual int handle_header(const std::string
& name
, const std::string
& val
);
27 void get_params_str(std::map
<std::string
, std::string
>& extra_args
, std::string
& dest
);
30 RGWHTTPSimpleRequest(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
,
31 param_vec_t
*_headers
, param_vec_t
*_params
) : RGWHTTPClient(_cct
, _method
, _url
),
32 http_status(0), status(0),
35 set_headers(_headers
);
39 void set_headers(param_vec_t
*_headers
) {
44 void set_params(param_vec_t
*_params
) {
49 int receive_header(void *ptr
, size_t len
) override
;
50 int receive_data(void *ptr
, size_t len
, bool *pause
) override
;
51 int send_data(void *ptr
, size_t len
, bool* pause
=nullptr) override
;
53 bufferlist
& get_response() { return response
; }
55 void get_out_headers(std::map
<std::string
, std::string
> *pheaders
); /* modifies out_headers */
57 int get_http_status() { return http_status
; }
61 class RGWRESTSimpleRequest
: public RGWHTTPSimpleRequest
{
62 std::optional
<std::string
> api_name
;
64 RGWRESTSimpleRequest(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
,
65 param_vec_t
*_headers
, param_vec_t
*_params
,
66 std::optional
<std::string
> _api_name
) : RGWHTTPSimpleRequest(_cct
, _method
, _url
, _headers
, _params
), api_name(_api_name
) {}
68 int forward_request(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, req_info
& info
, size_t max_response
, bufferlist
*inbl
, bufferlist
*outbl
, optional_yield y
);
71 class RGWWriteDrainCB
{
73 RGWWriteDrainCB() = default;
74 virtual ~RGWWriteDrainCB() = default;
75 virtual void notify(uint64_t pending_size
) = 0;
78 class RGWRESTGenerateHTTPHeaders
: public DoutPrefix
{
89 RGWRESTGenerateHTTPHeaders(CephContext
*_cct
, RGWEnv
*_env
, req_info
*_info
);
90 void init(const std::string
& method
, const std::string
& host
,
91 const std::string
& resource_prefix
, const std::string
& url
,
92 const std::string
& resource
, const param_vec_t
& params
,
93 std::optional
<std::string
> api_name
);
94 void set_extra_headers(const std::map
<std::string
, std::string
>& extra_headers
);
95 int set_obj_attrs(const DoutPrefixProvider
*dpp
, std::map
<std::string
, bufferlist
>& rgw_attrs
);
96 void set_http_attrs(const std::map
<std::string
, std::string
>& http_attrs
);
97 void set_policy(RGWAccessControlPolicy
& policy
);
98 int sign(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, const bufferlist
*opt_content
);
100 const std::string
& get_url() { return url
; }
103 class RGWHTTPStreamRWRequest
: public RGWHTTPSimpleRequest
{
109 ceph::make_mutex("RGWHTTPStreamRWRequest");
110 ceph::mutex write_lock
=
111 ceph::make_mutex("RGWHTTPStreamRWRequest::write_lock");
112 ReceiveCB
*cb
{nullptr};
113 RGWWriteDrainCB
*write_drain_cb
{nullptr};
117 uint64_t write_ofs
{0};
118 bool read_paused
{false};
119 bool send_paused
{false};
120 bool stream_writes
{false};
121 bool write_stream_complete
{false};
125 int handle_header(const std::string
& name
, const std::string
& val
) override
;
127 int send_data(void *ptr
, size_t len
, bool *pause
) override
;
128 int receive_data(void *ptr
, size_t len
, bool *pause
) override
;
132 uint64_t extra_data_len
{0};
134 ReceiveCB() = default;
135 virtual ~ReceiveCB() = default;
136 virtual int handle_data(bufferlist
& bl
, bool *pause
= nullptr) = 0;
137 virtual void set_extra_data_len(uint64_t len
) {
138 extra_data_len
= len
;
142 RGWHTTPStreamRWRequest(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
,
143 param_vec_t
*_headers
, param_vec_t
*_params
) : RGWHTTPSimpleRequest(_cct
, _method
, _url
, _headers
, _params
) {
145 RGWHTTPStreamRWRequest(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
, ReceiveCB
*_cb
,
146 param_vec_t
*_headers
, param_vec_t
*_params
) : RGWHTTPSimpleRequest(_cct
, _method
, _url
, _headers
, _params
),
149 virtual ~RGWHTTPStreamRWRequest() override
{}
151 void set_outbl(bufferlist
& _outbl
) {
155 void set_in_cb(ReceiveCB
*_cb
) { cb
= _cb
; }
156 void set_write_drain_cb(RGWWriteDrainCB
*_cb
) { write_drain_cb
= _cb
; }
158 void unpause_receive();
160 void add_send_data(bufferlist
& bl
);
162 void set_stream_write(bool s
);
164 uint64_t get_pending_send_size();
166 /* finish streaming writes */
169 int complete_request(optional_yield y
,
170 std::string
*etag
= nullptr,
171 real_time
*mtime
= nullptr,
172 uint64_t *psize
= nullptr,
173 std::map
<std::string
, std::string
> *pattrs
= nullptr,
174 std::map
<std::string
, std::string
> *pheaders
= nullptr);
177 class RGWRESTStreamRWRequest
: public RGWHTTPStreamRWRequest
{
178 std::optional
<RGWAccessKey
> sign_key
;
179 std::optional
<RGWRESTGenerateHTTPHeaders
> headers_gen
;
184 std::optional
<std::string
> api_name
;
185 HostStyle host_style
;
187 RGWRESTStreamRWRequest(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
, RGWHTTPStreamRWRequest::ReceiveCB
*_cb
,
188 param_vec_t
*_headers
, param_vec_t
*_params
,
189 std::optional
<std::string
> _api_name
, HostStyle _host_style
= PathStyle
) :
190 RGWHTTPStreamRWRequest(_cct
, _method
, _url
, _cb
, _headers
, _params
),
191 new_info(_cct
, &new_env
),
192 api_name(_api_name
), host_style(_host_style
) {
194 virtual ~RGWRESTStreamRWRequest() override
{}
196 int send_prepare(const DoutPrefixProvider
*dpp
, RGWAccessKey
*key
, std::map
<std::string
, std::string
>& extra_headers
, const std::string
& resource
, bufferlist
*send_data
= nullptr /* optional input data */);
197 int send_prepare(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, std::map
<std::string
, std::string
>& extra_headers
, const rgw_obj
& obj
);
198 int send(RGWHTTPManager
*mgr
);
200 int send_request(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, std::map
<std::string
, std::string
>& extra_headers
, const rgw_obj
& obj
, RGWHTTPManager
*mgr
);
201 int send_request(const DoutPrefixProvider
*dpp
, RGWAccessKey
*key
, std::map
<std::string
, std::string
>& extra_headers
, const std::string
& resource
, RGWHTTPManager
*mgr
, bufferlist
*send_data
= nullptr /* optional input data */);
203 void add_params(param_vec_t
*params
);
206 int do_send_prepare(const DoutPrefixProvider
*dpp
, RGWAccessKey
*key
, std::map
<std::string
, std::string
>& extra_headers
, const std::string
& resource
, bufferlist
*send_data
= nullptr /* optional input data */);
209 class RGWRESTStreamReadRequest
: public RGWRESTStreamRWRequest
{
211 RGWRESTStreamReadRequest(CephContext
*_cct
, const std::string
& _url
, ReceiveCB
*_cb
, param_vec_t
*_headers
,
212 param_vec_t
*_params
, std::optional
<std::string
> _api_name
,
213 HostStyle _host_style
= PathStyle
) : RGWRESTStreamRWRequest(_cct
, "GET", _url
, _cb
, _headers
, _params
, _api_name
, _host_style
) {}
216 class RGWRESTStreamHeadRequest
: public RGWRESTStreamRWRequest
{
218 RGWRESTStreamHeadRequest(CephContext
*_cct
, const std::string
& _url
, ReceiveCB
*_cb
, param_vec_t
*_headers
,
219 param_vec_t
*_params
, std::optional
<std::string
> _api_name
) : RGWRESTStreamRWRequest(_cct
, "HEAD", _url
, _cb
, _headers
, _params
, _api_name
) {}
222 class RGWRESTStreamSendRequest
: public RGWRESTStreamRWRequest
{
224 RGWRESTStreamSendRequest(CephContext
*_cct
, const std::string
& method
,
225 const std::string
& _url
,
226 ReceiveCB
*_cb
, param_vec_t
*_headers
, param_vec_t
*_params
,
227 std::optional
<std::string
> _api_name
,
228 HostStyle _host_style
= PathStyle
) : RGWRESTStreamRWRequest(_cct
, method
, _url
, _cb
, _headers
, _params
, _api_name
, _host_style
) {}
231 class RGWRESTStreamS3PutObj
: public RGWHTTPStreamRWRequest
{
232 std::optional
<std::string
> api_name
;
233 HostStyle host_style
;
234 RGWGetDataCB
*out_cb
;
237 RGWRESTGenerateHTTPHeaders headers_gen
;
239 RGWRESTStreamS3PutObj(CephContext
*_cct
, const std::string
& _method
, const std::string
& _url
, param_vec_t
*_headers
,
240 param_vec_t
*_params
, std::optional
<std::string
> _api_name
,
241 HostStyle _host_style
) : RGWHTTPStreamRWRequest(_cct
, _method
, _url
, nullptr, _headers
, _params
),
242 api_name(_api_name
), host_style(_host_style
),
243 out_cb(NULL
), new_info(cct
, &new_env
), headers_gen(_cct
, &new_env
, &new_info
) {}
244 ~RGWRESTStreamS3PutObj() override
;
246 void send_init(rgw::sal::Object
* obj
);
247 void send_ready(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, std::map
<std::string
, bufferlist
>& rgw_attrs
);
248 void send_ready(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, const std::map
<std::string
, std::string
>& http_attrs
,
249 RGWAccessControlPolicy
& policy
);
250 void send_ready(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
);
252 void put_obj_init(const DoutPrefixProvider
*dpp
, RGWAccessKey
& key
, rgw::sal::Object
* obj
, std::map
<std::string
, bufferlist
>& attrs
);
254 RGWGetDataCB
*get_out_cb() { return out_cb
; }