]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #ifndef CEPH_RGW_REST_H | |
5 | #define CEPH_RGW_REST_H | |
6 | ||
7 | #define TIME_BUF_SIZE 128 | |
8 | ||
9 | #include <boost/utility/string_ref.hpp> | |
10 | #include <boost/container/flat_set.hpp> | |
11 | #include "common/sstring.hh" | |
12 | #include "common/ceph_json.h" | |
13 | #include "include/assert.h" /* needed because of common/ceph_json.h */ | |
14 | #include "rgw_op.h" | |
15 | #include "rgw_formats.h" | |
16 | #include "rgw_client_io.h" | |
17 | ||
18 | extern std::map<std::string, std::string> rgw_to_http_attrs; | |
19 | ||
20 | extern string camelcase_dash_http_attr(const string& orig); | |
21 | extern string lowercase_dash_http_attr(const string& orig); | |
22 | ||
23 | extern void rgw_rest_init(CephContext *cct, RGWRados *store, RGWZoneGroup& zone_group); | |
24 | ||
25 | extern void rgw_flush_formatter_and_reset(struct req_state *s, | |
26 | ceph::Formatter *formatter); | |
27 | ||
28 | extern void rgw_flush_formatter(struct req_state *s, | |
29 | ceph::Formatter *formatter); | |
30 | ||
31 | extern int rgw_rest_read_all_input(struct req_state *s, char **data, int *plen, | |
32 | uint64_t max_len, bool allow_chunked=true); | |
33 | ||
34 | template <class T> | |
35 | int rgw_rest_get_json_input(CephContext *cct, req_state *s, T& out, | |
36 | uint64_t max_len, bool *empty) | |
37 | { | |
38 | int rv, data_len; | |
39 | char *data; | |
40 | ||
41 | if (empty) | |
42 | *empty = false; | |
43 | ||
44 | if ((rv = rgw_rest_read_all_input(s, &data, &data_len, max_len)) < 0) { | |
45 | return rv; | |
46 | } | |
47 | ||
48 | if (!data_len) { | |
49 | if (empty) { | |
50 | *empty = true; | |
51 | } | |
52 | ||
53 | return -EINVAL; | |
54 | } | |
55 | ||
56 | JSONParser parser; | |
57 | ||
58 | if (!parser.parse(data, data_len)) { | |
59 | free(data); | |
60 | return -EINVAL; | |
61 | } | |
62 | ||
63 | free(data); | |
64 | ||
65 | try { | |
66 | decode_json_obj(out, &parser); | |
67 | } catch (JSONDecoder::err& e) { | |
68 | return -EINVAL; | |
69 | } | |
70 | ||
71 | return 0; | |
72 | } | |
73 | ||
74 | template <class T> | |
75 | int rgw_rest_get_json_input_keep_data(CephContext *cct, req_state *s, T& out, uint64_t max_len, char **pdata, int *len) | |
76 | { | |
77 | int rv, data_len; | |
78 | char *data; | |
79 | ||
80 | if ((rv = rgw_rest_read_all_input(s, &data, &data_len, max_len)) < 0) { | |
81 | return rv; | |
82 | } | |
83 | ||
84 | if (!data_len) { | |
85 | return -EINVAL; | |
86 | } | |
87 | ||
88 | *len = data_len; | |
89 | ||
90 | JSONParser parser; | |
91 | ||
92 | if (!parser.parse(data, data_len)) { | |
93 | free(data); | |
94 | return -EINVAL; | |
95 | } | |
96 | ||
97 | try { | |
98 | decode_json_obj(out, &parser); | |
99 | } catch (JSONDecoder::err& e) { | |
100 | free(data); | |
101 | return -EINVAL; | |
102 | } | |
103 | ||
104 | *pdata = data; | |
105 | return 0; | |
106 | } | |
107 | ||
108 | class RESTArgs { | |
109 | public: | |
110 | static int get_string(struct req_state *s, const string& name, | |
111 | const string& def_val, string *val, | |
112 | bool *existed = NULL); | |
113 | static int get_uint64(struct req_state *s, const string& name, | |
114 | uint64_t def_val, uint64_t *val, bool *existed = NULL); | |
115 | static int get_int64(struct req_state *s, const string& name, | |
116 | int64_t def_val, int64_t *val, bool *existed = NULL); | |
117 | static int get_uint32(struct req_state *s, const string& name, | |
118 | uint32_t def_val, uint32_t *val, bool *existed = NULL); | |
119 | static int get_int32(struct req_state *s, const string& name, | |
120 | int32_t def_val, int32_t *val, bool *existed = NULL); | |
121 | static int get_time(struct req_state *s, const string& name, | |
122 | const utime_t& def_val, utime_t *val, | |
123 | bool *existed = NULL); | |
124 | static int get_epoch(struct req_state *s, const string& name, | |
125 | uint64_t def_val, uint64_t *epoch, | |
126 | bool *existed = NULL); | |
127 | static int get_bool(struct req_state *s, const string& name, bool def_val, | |
128 | bool *val, bool *existed = NULL); | |
129 | }; | |
130 | ||
131 | class RGWRESTFlusher : public RGWFormatterFlusher { | |
132 | struct req_state *s; | |
133 | RGWOp *op; | |
134 | protected: | |
135 | void do_flush() override; | |
136 | void do_start(int ret) override; | |
137 | public: | |
138 | RGWRESTFlusher(struct req_state *_s, RGWOp *_op) : | |
139 | RGWFormatterFlusher(_s->formatter), s(_s), op(_op) {} | |
140 | RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL), op(NULL) {} | |
141 | ||
142 | void init(struct req_state *_s, RGWOp *_op) { | |
143 | s = _s; | |
144 | op = _op; | |
145 | set_formatter(s->formatter); | |
146 | } | |
147 | }; | |
148 | ||
149 | class RGWGetObj_ObjStore : public RGWGetObj | |
150 | { | |
151 | protected: | |
152 | bool sent_header; | |
153 | public: | |
154 | RGWGetObj_ObjStore() : sent_header(false) {} | |
155 | ||
156 | void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { | |
157 | RGWGetObj::init(store, s, h); | |
158 | sent_header = false; | |
159 | } | |
160 | ||
161 | int get_params() override; | |
162 | }; | |
163 | ||
224ce89b WB |
164 | class RGWGetObjTags_ObjStore : public RGWGetObjTags { |
165 | public: | |
166 | RGWGetObjTags_ObjStore() {}; | |
167 | ~RGWGetObjTags_ObjStore() {}; | |
168 | }; | |
169 | ||
170 | class RGWPutObjTags_ObjStore: public RGWPutObjTags { | |
171 | public: | |
172 | RGWPutObjTags_ObjStore() {}; | |
173 | ~RGWPutObjTags_ObjStore() {}; | |
174 | }; | |
175 | ||
7c673cae FG |
176 | class RGWListBuckets_ObjStore : public RGWListBuckets { |
177 | public: | |
178 | RGWListBuckets_ObjStore() {} | |
179 | ~RGWListBuckets_ObjStore() override {} | |
180 | }; | |
181 | ||
182 | class RGWGetUsage_ObjStore : public RGWGetUsage { | |
183 | public: | |
184 | RGWGetUsage_ObjStore() {} | |
185 | ~RGWGetUsage_ObjStore() override {} | |
186 | }; | |
187 | ||
188 | class RGWListBucket_ObjStore : public RGWListBucket { | |
189 | public: | |
190 | RGWListBucket_ObjStore() {} | |
191 | ~RGWListBucket_ObjStore() override {} | |
192 | }; | |
193 | ||
194 | class RGWStatAccount_ObjStore : public RGWStatAccount { | |
195 | public: | |
196 | RGWStatAccount_ObjStore() {} | |
197 | ~RGWStatAccount_ObjStore() override {} | |
198 | }; | |
199 | ||
200 | class RGWStatBucket_ObjStore : public RGWStatBucket { | |
201 | public: | |
202 | RGWStatBucket_ObjStore() {} | |
203 | ~RGWStatBucket_ObjStore() override {} | |
204 | }; | |
205 | ||
206 | class RGWCreateBucket_ObjStore : public RGWCreateBucket { | |
207 | public: | |
208 | RGWCreateBucket_ObjStore() {} | |
209 | ~RGWCreateBucket_ObjStore() override {} | |
210 | }; | |
211 | ||
212 | class RGWDeleteBucket_ObjStore : public RGWDeleteBucket { | |
213 | public: | |
214 | RGWDeleteBucket_ObjStore() {} | |
215 | ~RGWDeleteBucket_ObjStore() override {} | |
216 | }; | |
217 | ||
218 | class RGWPutObj_ObjStore : public RGWPutObj | |
219 | { | |
220 | public: | |
221 | RGWPutObj_ObjStore() {} | |
222 | ~RGWPutObj_ObjStore() override {} | |
223 | ||
224 | int verify_params() override; | |
225 | int get_params() override; | |
226 | int get_data(bufferlist& bl) override; | |
7c673cae FG |
227 | }; |
228 | ||
229 | class RGWPostObj_ObjStore : public RGWPostObj | |
230 | { | |
231 | std::string boundary; | |
232 | ||
233 | public: | |
234 | struct post_part_field { | |
235 | std::string val; | |
236 | std::map<std::string, std::string> params; | |
237 | }; | |
238 | ||
239 | struct post_form_part { | |
240 | std::string name; | |
241 | std::map<std::string, post_part_field, ltstr_nocase> fields; | |
242 | ceph::bufferlist data; | |
243 | }; | |
244 | ||
245 | protected: | |
246 | using parts_collection_t = \ | |
247 | std::map<std::string, post_form_part, const ltstr_nocase>; | |
248 | ||
249 | std::string err_msg; | |
250 | ceph::bufferlist in_data; | |
251 | ||
252 | int read_with_boundary(ceph::bufferlist& bl, | |
253 | uint64_t max, | |
254 | bool check_eol, | |
255 | bool& reached_boundary, | |
256 | bool& done); | |
257 | ||
258 | int read_line(ceph::bufferlist& bl, | |
259 | uint64_t max, | |
260 | bool& reached_boundary, | |
261 | bool& done); | |
262 | ||
263 | int read_data(ceph::bufferlist& bl, | |
264 | uint64_t max, | |
265 | bool& reached_boundary, | |
266 | bool& done); | |
267 | ||
268 | int read_form_part_header(struct post_form_part *part, bool& done); | |
269 | ||
270 | int get_params() override; | |
271 | ||
272 | static int parse_part_field(const std::string& line, | |
273 | std::string& field_name, /* out */ | |
274 | post_part_field& field); /* out */ | |
275 | ||
276 | static void parse_boundary_params(const std::string& params_str, | |
277 | std::string& first, | |
278 | std::map<std::string, std::string>& params); | |
279 | ||
280 | static bool part_str(parts_collection_t& parts, | |
281 | const std::string& name, | |
282 | std::string *val); | |
283 | ||
284 | static std::string get_part_str(parts_collection_t& parts, | |
285 | const std::string& name, | |
286 | const std::string& def_val = std::string()); | |
287 | ||
288 | static bool part_bl(parts_collection_t& parts, | |
289 | const std::string& name, | |
290 | ceph::bufferlist *pbl); | |
291 | ||
292 | public: | |
293 | RGWPostObj_ObjStore() {} | |
294 | ~RGWPostObj_ObjStore() override {} | |
295 | ||
296 | int verify_params() override; | |
297 | }; | |
298 | ||
299 | ||
300 | class RGWPutMetadataAccount_ObjStore : public RGWPutMetadataAccount | |
301 | { | |
302 | public: | |
303 | RGWPutMetadataAccount_ObjStore() {} | |
304 | ~RGWPutMetadataAccount_ObjStore() override {} | |
305 | }; | |
306 | ||
307 | class RGWPutMetadataBucket_ObjStore : public RGWPutMetadataBucket | |
308 | { | |
309 | public: | |
310 | RGWPutMetadataBucket_ObjStore() {} | |
311 | ~RGWPutMetadataBucket_ObjStore() override {} | |
312 | }; | |
313 | ||
314 | class RGWPutMetadataObject_ObjStore : public RGWPutMetadataObject | |
315 | { | |
316 | public: | |
317 | RGWPutMetadataObject_ObjStore() {} | |
318 | ~RGWPutMetadataObject_ObjStore() override {} | |
319 | }; | |
320 | ||
321 | class RGWDeleteObj_ObjStore : public RGWDeleteObj { | |
322 | public: | |
323 | RGWDeleteObj_ObjStore() {} | |
324 | ~RGWDeleteObj_ObjStore() override {} | |
325 | }; | |
326 | ||
327 | class RGWGetCrossDomainPolicy_ObjStore : public RGWGetCrossDomainPolicy { | |
328 | public: | |
329 | RGWGetCrossDomainPolicy_ObjStore() = default; | |
330 | ~RGWGetCrossDomainPolicy_ObjStore() override = default; | |
331 | }; | |
332 | ||
333 | class RGWGetHealthCheck_ObjStore : public RGWGetHealthCheck { | |
334 | public: | |
335 | RGWGetHealthCheck_ObjStore() = default; | |
336 | ~RGWGetHealthCheck_ObjStore() override = default; | |
337 | }; | |
338 | ||
339 | class RGWCopyObj_ObjStore : public RGWCopyObj { | |
340 | public: | |
341 | RGWCopyObj_ObjStore() {} | |
342 | ~RGWCopyObj_ObjStore() override {} | |
343 | }; | |
344 | ||
345 | class RGWGetACLs_ObjStore : public RGWGetACLs { | |
346 | public: | |
347 | RGWGetACLs_ObjStore() {} | |
348 | ~RGWGetACLs_ObjStore() override {} | |
349 | }; | |
350 | ||
351 | class RGWPutACLs_ObjStore : public RGWPutACLs { | |
352 | public: | |
353 | RGWPutACLs_ObjStore() {} | |
354 | ~RGWPutACLs_ObjStore() override {} | |
355 | ||
356 | int get_params() override; | |
357 | }; | |
358 | ||
359 | class RGWGetLC_ObjStore : public RGWGetLC { | |
360 | public: | |
361 | RGWGetLC_ObjStore() {} | |
362 | ~RGWGetLC_ObjStore() override {} | |
363 | }; | |
364 | ||
365 | class RGWPutLC_ObjStore : public RGWPutLC { | |
366 | public: | |
367 | RGWPutLC_ObjStore() {} | |
368 | ~RGWPutLC_ObjStore() override {} | |
369 | ||
370 | int get_params() override; | |
371 | }; | |
372 | ||
373 | class RGWDeleteLC_ObjStore : public RGWDeleteLC { | |
374 | public: | |
375 | RGWDeleteLC_ObjStore() {} | |
376 | ~RGWDeleteLC_ObjStore() override {} | |
377 | ||
378 | }; | |
379 | ||
380 | class RGWGetCORS_ObjStore : public RGWGetCORS { | |
381 | public: | |
382 | RGWGetCORS_ObjStore() {} | |
383 | ~RGWGetCORS_ObjStore() override {} | |
384 | }; | |
385 | ||
386 | class RGWPutCORS_ObjStore : public RGWPutCORS { | |
387 | public: | |
388 | RGWPutCORS_ObjStore() {} | |
389 | ~RGWPutCORS_ObjStore() override {} | |
390 | }; | |
391 | ||
392 | class RGWDeleteCORS_ObjStore : public RGWDeleteCORS { | |
393 | public: | |
394 | RGWDeleteCORS_ObjStore() {} | |
395 | ~RGWDeleteCORS_ObjStore() override {} | |
396 | }; | |
397 | ||
398 | class RGWOptionsCORS_ObjStore : public RGWOptionsCORS { | |
399 | public: | |
400 | RGWOptionsCORS_ObjStore() {} | |
401 | ~RGWOptionsCORS_ObjStore() override {} | |
402 | }; | |
403 | ||
404 | class RGWInitMultipart_ObjStore : public RGWInitMultipart { | |
405 | public: | |
406 | RGWInitMultipart_ObjStore() {} | |
407 | ~RGWInitMultipart_ObjStore() override {} | |
408 | }; | |
409 | ||
410 | class RGWCompleteMultipart_ObjStore : public RGWCompleteMultipart { | |
411 | public: | |
412 | RGWCompleteMultipart_ObjStore() {} | |
413 | ~RGWCompleteMultipart_ObjStore() override {} | |
414 | ||
415 | int get_params() override; | |
416 | }; | |
417 | ||
418 | class RGWAbortMultipart_ObjStore : public RGWAbortMultipart { | |
419 | public: | |
420 | RGWAbortMultipart_ObjStore() {} | |
421 | ~RGWAbortMultipart_ObjStore() override {} | |
422 | }; | |
423 | ||
424 | class RGWListMultipart_ObjStore : public RGWListMultipart { | |
425 | public: | |
426 | RGWListMultipart_ObjStore() {} | |
427 | ~RGWListMultipart_ObjStore() override {} | |
428 | ||
429 | int get_params() override; | |
430 | }; | |
431 | ||
432 | class RGWListBucketMultiparts_ObjStore : public RGWListBucketMultiparts { | |
433 | public: | |
434 | RGWListBucketMultiparts_ObjStore() {} | |
435 | ~RGWListBucketMultiparts_ObjStore() override {} | |
436 | ||
437 | int get_params() override; | |
438 | }; | |
439 | ||
440 | class RGWBulkDelete_ObjStore : public RGWBulkDelete { | |
441 | public: | |
442 | RGWBulkDelete_ObjStore() {} | |
443 | ~RGWBulkDelete_ObjStore() override {} | |
444 | }; | |
445 | ||
446 | class RGWBulkUploadOp_ObjStore : public RGWBulkUploadOp { | |
447 | public: | |
448 | RGWBulkUploadOp_ObjStore() = default; | |
449 | ~RGWBulkUploadOp_ObjStore() = default; | |
450 | }; | |
451 | ||
452 | class RGWDeleteMultiObj_ObjStore : public RGWDeleteMultiObj { | |
453 | public: | |
454 | RGWDeleteMultiObj_ObjStore() {} | |
455 | ~RGWDeleteMultiObj_ObjStore() override {} | |
456 | ||
457 | int get_params() override; | |
458 | }; | |
459 | ||
460 | class RGWInfo_ObjStore : public RGWInfo { | |
461 | public: | |
462 | RGWInfo_ObjStore() = default; | |
463 | ~RGWInfo_ObjStore() override = default; | |
464 | }; | |
465 | ||
466 | class RGWRESTOp : public RGWOp { | |
467 | protected: | |
468 | int http_ret; | |
469 | RGWRESTFlusher flusher; | |
470 | public: | |
471 | RGWRESTOp() : http_ret(0) {} | |
472 | void init(RGWRados *store, struct req_state *s, | |
473 | RGWHandler *dialect_handler) override { | |
474 | RGWOp::init(store, s, dialect_handler); | |
475 | flusher.init(s, this); | |
476 | } | |
477 | void send_response() override; | |
478 | virtual int check_caps(RGWUserCaps& caps) | |
479 | { return -EPERM; } /* should to be implemented! */ | |
480 | int verify_permission() override; | |
481 | }; | |
482 | ||
483 | class RGWHandler_REST : public RGWHandler { | |
484 | protected: | |
485 | ||
486 | virtual bool is_obj_update_op() { return false; } | |
487 | virtual RGWOp *op_get() { return NULL; } | |
488 | virtual RGWOp *op_put() { return NULL; } | |
489 | virtual RGWOp *op_delete() { return NULL; } | |
490 | virtual RGWOp *op_head() { return NULL; } | |
491 | virtual RGWOp *op_post() { return NULL; } | |
492 | virtual RGWOp *op_copy() { return NULL; } | |
493 | virtual RGWOp *op_options() { return NULL; } | |
494 | ||
495 | static int allocate_formatter(struct req_state *s, int default_formatter, | |
496 | bool configurable); | |
497 | public: | |
498 | static constexpr int MAX_BUCKET_NAME_LEN = 255; | |
499 | static constexpr int MAX_OBJ_NAME_LEN = 1024; | |
500 | ||
501 | RGWHandler_REST() {} | |
502 | ~RGWHandler_REST() override {} | |
503 | ||
7c673cae FG |
504 | static int validate_bucket_name(const string& bucket); |
505 | static int validate_object_name(const string& object); | |
506 | ||
507 | int init_permissions(RGWOp* op) override; | |
508 | int read_permissions(RGWOp* op) override; | |
509 | ||
510 | virtual RGWOp* get_op(RGWRados* store); | |
511 | virtual void put_op(RGWOp* op); | |
512 | }; | |
513 | ||
514 | class RGWHandler_REST_SWIFT; | |
515 | class RGWHandler_SWIFT_Auth; | |
516 | class RGWHandler_REST_S3; | |
517 | ||
518 | namespace rgw { | |
519 | namespace auth { | |
520 | ||
521 | class StrategyRegistry; | |
522 | ||
523 | } | |
524 | } | |
525 | ||
526 | class RGWRESTMgr { | |
527 | bool should_log; | |
528 | ||
529 | protected: | |
530 | std::map<std::string, RGWRESTMgr*> resource_mgrs; | |
531 | std::multimap<size_t, std::string> resources_by_size; | |
532 | RGWRESTMgr* default_mgr; | |
533 | ||
534 | virtual RGWRESTMgr* get_resource_mgr(struct req_state* s, | |
535 | const std::string& uri, | |
536 | std::string* out_uri); | |
537 | ||
538 | virtual RGWRESTMgr* get_resource_mgr_as_default(struct req_state* const s, | |
539 | const std::string& uri, | |
540 | std::string* our_uri) { | |
541 | return this; | |
542 | } | |
543 | ||
544 | public: | |
545 | RGWRESTMgr() | |
546 | : should_log(false), | |
547 | default_mgr(nullptr) { | |
548 | } | |
549 | virtual ~RGWRESTMgr(); | |
550 | ||
551 | void register_resource(std::string resource, RGWRESTMgr* mgr); | |
552 | void register_default_mgr(RGWRESTMgr* mgr); | |
553 | ||
554 | virtual RGWRESTMgr* get_manager(struct req_state* const s, | |
555 | /* Prefix to be concatenated with @uri | |
556 | * during the lookup. */ | |
557 | const std::string& frontend_prefix, | |
558 | const std::string& uri, | |
559 | std::string* out_uri) final { | |
560 | return get_resource_mgr(s, frontend_prefix + uri, out_uri); | |
561 | } | |
562 | ||
563 | virtual RGWHandler_REST* get_handler( | |
564 | struct req_state* const s, | |
565 | const rgw::auth::StrategyRegistry& auth_registry, | |
566 | const std::string& frontend_prefix | |
567 | ) { | |
568 | return nullptr; | |
569 | } | |
570 | ||
571 | virtual void put_handler(RGWHandler_REST* const handler) { | |
572 | delete handler; | |
573 | } | |
574 | ||
575 | void set_logging(bool _should_log) { | |
576 | should_log = _should_log; | |
577 | } | |
578 | ||
579 | bool get_logging() const { | |
580 | return should_log; | |
581 | } | |
582 | }; | |
583 | ||
584 | class RGWLibIO; | |
585 | class RGWRestfulIO; | |
586 | ||
587 | class RGWREST { | |
588 | using x_header = basic_sstring<char, uint16_t, 32>; | |
589 | boost::container::flat_set<x_header> x_headers; | |
590 | RGWRESTMgr mgr; | |
591 | ||
592 | static int preprocess(struct req_state *s, rgw::io::BasicClient* rio); | |
593 | public: | |
594 | RGWREST() {} | |
595 | RGWHandler_REST *get_handler(RGWRados *store, | |
596 | struct req_state *s, | |
597 | const rgw::auth::StrategyRegistry& auth_registry, | |
598 | const std::string& frontend_prefix, | |
599 | RGWRestfulIO *rio, | |
600 | RGWRESTMgr **pmgr, | |
601 | int *init_error); | |
602 | #if 0 | |
603 | RGWHandler *get_handler(RGWRados *store, struct req_state *s, | |
604 | RGWLibIO *io, RGWRESTMgr **pmgr, | |
605 | int *init_error); | |
606 | #endif | |
607 | ||
608 | void put_handler(RGWHandler_REST *handler) { | |
609 | mgr.put_handler(handler); | |
610 | } | |
611 | ||
612 | void register_resource(string resource, RGWRESTMgr *m, | |
613 | bool register_empty = false) { | |
614 | if (!register_empty && resource.empty()) | |
615 | return; | |
616 | ||
617 | mgr.register_resource(resource, m); | |
618 | } | |
619 | ||
620 | void register_default_mgr(RGWRESTMgr *m) { | |
621 | mgr.register_default_mgr(m); | |
622 | } | |
623 | ||
624 | void register_x_headers(const std::string& headers); | |
625 | ||
626 | bool log_x_headers(void) { | |
627 | return (x_headers.size() > 0); | |
628 | } | |
629 | ||
630 | bool log_x_header(const std::string& header) { | |
631 | return (x_headers.find(header) != x_headers.end()); | |
632 | } | |
633 | }; | |
634 | ||
635 | static constexpr int64_t NO_CONTENT_LENGTH = -1; | |
636 | static constexpr int64_t CHUNKED_TRANSFER_ENCODING = -2; | |
637 | ||
7c673cae FG |
638 | extern void dump_errno(int http_ret, string& out); |
639 | extern void dump_errno(const struct rgw_err &err, string& out); | |
640 | extern void dump_errno(struct req_state *s); | |
641 | extern void dump_errno(struct req_state *s, int http_ret); | |
642 | extern void end_header(struct req_state *s, | |
643 | RGWOp* op = nullptr, | |
644 | const char *content_type = nullptr, | |
645 | const int64_t proposed_content_length = | |
646 | NO_CONTENT_LENGTH, | |
647 | bool force_content_type = false, | |
648 | bool force_no_error = false); | |
649 | extern void dump_start(struct req_state *s); | |
650 | extern void list_all_buckets_start(struct req_state *s); | |
651 | extern void dump_owner(struct req_state *s, const rgw_user& id, string& name, | |
652 | const char *section = NULL); | |
653 | extern void dump_header(struct req_state* s, | |
654 | const boost::string_ref& name, | |
655 | const boost::string_ref& val); | |
656 | extern void dump_header(struct req_state* s, | |
657 | const boost::string_ref& name, | |
658 | ceph::buffer::list& bl); | |
659 | extern void dump_header(struct req_state* s, | |
660 | const boost::string_ref& name, | |
661 | long long val); | |
662 | extern void dump_header(struct req_state* s, | |
663 | const boost::string_ref& name, | |
664 | const utime_t& val); | |
3efd9988 | 665 | |
7c673cae FG |
666 | template <class... Args> |
667 | static inline void dump_header_prefixed(struct req_state* s, | |
668 | const boost::string_ref& name_prefix, | |
669 | const boost::string_ref& name, | |
670 | Args&&... args) { | |
671 | char full_name_buf[name_prefix.size() + name.size() + 1]; | |
672 | const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s", | |
673 | static_cast<int>(name_prefix.length()), | |
674 | name_prefix.data(), | |
675 | static_cast<int>(name.length()), | |
676 | name.data()); | |
677 | boost::string_ref full_name(full_name_buf, len); | |
678 | return dump_header(s, std::move(full_name), std::forward<Args>(args)...); | |
679 | } | |
680 | ||
3efd9988 FG |
681 | template <class... Args> |
682 | static inline void dump_header_infixed(struct req_state* s, | |
683 | const boost::string_ref& prefix, | |
684 | const boost::string_ref& infix, | |
685 | const boost::string_ref& sufix, | |
686 | Args&&... args) { | |
687 | char full_name_buf[prefix.size() + infix.size() + sufix.size() + 1]; | |
688 | const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s%.*s", | |
689 | static_cast<int>(prefix.length()), | |
690 | prefix.data(), | |
691 | static_cast<int>(infix.length()), | |
692 | infix.data(), | |
693 | static_cast<int>(sufix.length()), | |
694 | sufix.data()); | |
695 | boost::string_ref full_name(full_name_buf, len); | |
696 | return dump_header(s, std::move(full_name), std::forward<Args>(args)...); | |
697 | } | |
698 | ||
7c673cae FG |
699 | template <class... Args> |
700 | static inline void dump_header_quoted(struct req_state* s, | |
701 | const boost::string_ref& name, | |
702 | const boost::string_ref& val) { | |
703 | /* We need two extra bytes for quotes. */ | |
704 | char qvalbuf[val.size() + 2 + 1]; | |
705 | const auto len = snprintf(qvalbuf, sizeof(qvalbuf), "\"%.*s\"", | |
706 | static_cast<int>(val.length()), val.data()); | |
707 | return dump_header(s, name, boost::string_ref(qvalbuf, len)); | |
708 | } | |
709 | ||
710 | template <class ValueT> | |
711 | static inline void dump_header_if_nonempty(struct req_state* s, | |
712 | const boost::string_ref& name, | |
713 | const ValueT& value) { | |
714 | if (name.length() > 0 && value.length() > 0) { | |
715 | return dump_header(s, name, value); | |
716 | } | |
717 | } | |
718 | ||
719 | extern void dump_content_length(struct req_state *s, uint64_t len); | |
31f18b77 | 720 | extern int64_t parse_content_length(const char *content_length); |
7c673cae FG |
721 | extern void dump_etag(struct req_state *s, |
722 | const boost::string_ref& etag, | |
723 | bool quoted = false); | |
724 | extern void dump_etag(struct req_state *s, | |
725 | ceph::buffer::list& bl_etag, | |
726 | bool quoted = false); | |
727 | extern void dump_epoch_header(struct req_state *s, const char *name, real_time t); | |
728 | extern void dump_time_header(struct req_state *s, const char *name, real_time t); | |
729 | extern void dump_last_modified(struct req_state *s, real_time t); | |
730 | extern void abort_early(struct req_state* s, RGWOp* op, int err, | |
731 | RGWHandler* handler); | |
732 | extern void dump_range(struct req_state* s, uint64_t ofs, uint64_t end, | |
733 | uint64_t total_size); | |
734 | extern void dump_continue(struct req_state *s); | |
735 | extern void list_all_buckets_end(struct req_state *s); | |
736 | extern void dump_time(struct req_state *s, const char *name, real_time *t); | |
737 | extern std::string dump_time_to_str(const real_time& t); | |
738 | extern void dump_bucket_from_state(struct req_state *s); | |
739 | extern void dump_uri_from_state(struct req_state *s); | |
740 | extern void dump_redirect(struct req_state *s, const string& redirect); | |
741 | extern bool is_valid_url(const char *url); | |
742 | extern void dump_access_control(struct req_state *s, const char *origin, | |
743 | const char *meth, | |
744 | const char *hdr, const char *exp_hdr, | |
745 | uint32_t max_age); | |
746 | extern void dump_access_control(req_state *s, RGWOp *op); | |
747 | ||
748 | extern int dump_body(struct req_state* s, const char* buf, size_t len); | |
749 | extern int dump_body(struct req_state* s, /* const */ ceph::buffer::list& bl); | |
750 | extern int dump_body(struct req_state* s, const std::string& str); | |
751 | ||
752 | extern int recv_body(struct req_state* s, char* buf, size_t max); | |
753 | ||
754 | #endif /* CEPH_RGW_REST_H */ |