]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_client.h
caf6ffa35c80274391ec9a86a5da4e4895d039c2
[ceph.git] / ceph / src / rgw / rgw_rest_client.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #pragma once
5
6 #include "rgw_http_client.h"
7
8 class RGWGetDataCB;
9
10 class RGWHTTPSimpleRequest : public RGWHTTPClient {
11 protected:
12 int http_status;
13 int status;
14
15 using unique_lock = std::unique_lock<std::mutex>;
16
17 std::mutex out_headers_lock;
18 std::map<std::string, std::string> out_headers;
19 param_vec_t params;
20
21 bufferlist::iterator *send_iter;
22
23 size_t max_response; /* we need this as we don't stream out response */
24 bufferlist response;
25
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);
28
29 public:
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),
33 send_iter(NULL),
34 max_response(0) {
35 set_headers(_headers);
36 set_params(_params);
37 }
38
39 void set_headers(param_vec_t *_headers) {
40 if (_headers)
41 headers = *_headers;
42 }
43
44 void set_params(param_vec_t *_params) {
45 if (_params)
46 params = *_params;
47 }
48
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;
52
53 bufferlist& get_response() { return response; }
54
55 void get_out_headers(std::map<std::string, std::string> *pheaders); /* modifies out_headers */
56
57 int get_http_status() { return http_status; }
58 int get_status();
59 };
60
61 class RGWRESTSimpleRequest : public RGWHTTPSimpleRequest {
62 std::optional<std::string> api_name;
63 public:
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) {}
67
68 int forward_request(const DoutPrefixProvider *dpp, RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y);
69 };
70
71 class RGWWriteDrainCB {
72 public:
73 RGWWriteDrainCB() = default;
74 virtual ~RGWWriteDrainCB() = default;
75 virtual void notify(uint64_t pending_size) = 0;
76 };
77
78 class RGWRESTGenerateHTTPHeaders : public DoutPrefix {
79 CephContext *cct;
80 RGWEnv *new_env;
81 req_info *new_info;
82 std::string region;
83 std::string service;
84 std::string method;
85 std::string url;
86 std::string resource;
87
88 public:
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);
99
100 const std::string& get_url() { return url; }
101 };
102
103 class RGWHTTPStreamRWRequest : public RGWHTTPSimpleRequest {
104 public:
105 class ReceiveCB;
106
107 private:
108 ceph::mutex lock =
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};
114 bufferlist in_data;
115 size_t chunk_ofs{0};
116 size_t ofs{0};
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};
122 protected:
123 bufferlist outbl;
124
125 int handle_header(const std::string& name, const std::string& val) override;
126 public:
127 int send_data(void *ptr, size_t len, bool *pause) override;
128 int receive_data(void *ptr, size_t len, bool *pause) override;
129
130 class ReceiveCB {
131 protected:
132 uint64_t extra_data_len{0};
133 public:
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;
139 }
140 };
141
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) {
144 }
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),
147 cb(_cb) {
148 }
149 virtual ~RGWHTTPStreamRWRequest() override {}
150
151 void set_outbl(bufferlist& _outbl) {
152 outbl.swap(_outbl);
153 }
154
155 void set_in_cb(ReceiveCB *_cb) { cb = _cb; }
156 void set_write_drain_cb(RGWWriteDrainCB *_cb) { write_drain_cb = _cb; }
157
158 void unpause_receive();
159
160 void add_send_data(bufferlist& bl);
161
162 void set_stream_write(bool s);
163
164 uint64_t get_pending_send_size();
165
166 /* finish streaming writes */
167 void finish_write();
168
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);
175 };
176
177 class RGWRESTStreamRWRequest : public RGWHTTPStreamRWRequest {
178 std::optional<RGWAccessKey> sign_key;
179 std::optional<RGWRESTGenerateHTTPHeaders> headers_gen;
180 RGWEnv new_env;
181 req_info new_info;
182
183 protected:
184 std::optional<std::string> api_name;
185 HostStyle host_style;
186 public:
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) {
193 }
194 virtual ~RGWRESTStreamRWRequest() override {}
195
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);
199
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 */);
202
203 void add_params(param_vec_t *params);
204
205 private:
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 */);
207 };
208
209 class RGWRESTStreamReadRequest : public RGWRESTStreamRWRequest {
210 public:
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) {}
214 };
215
216 class RGWRESTStreamHeadRequest : public RGWRESTStreamRWRequest {
217 public:
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) {}
220 };
221
222 class RGWRESTStreamSendRequest : public RGWRESTStreamRWRequest {
223 public:
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) {}
229 };
230
231 class RGWRESTStreamS3PutObj : public RGWHTTPStreamRWRequest {
232 std::optional<std::string> api_name;
233 HostStyle host_style;
234 RGWGetDataCB *out_cb;
235 RGWEnv new_env;
236 req_info new_info;
237 RGWRESTGenerateHTTPHeaders headers_gen;
238 public:
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;
245
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);
251
252 void put_obj_init(const DoutPrefixProvider *dpp, RGWAccessKey& key, rgw::sal::Object* obj, std::map<std::string, bufferlist>& attrs);
253
254 RGWGetDataCB *get_out_cb() { return out_cb; }
255 };