]>
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 | ||
164 | class RGWListBuckets_ObjStore : public RGWListBuckets { | |
165 | public: | |
166 | RGWListBuckets_ObjStore() {} | |
167 | ~RGWListBuckets_ObjStore() override {} | |
168 | }; | |
169 | ||
170 | class RGWGetUsage_ObjStore : public RGWGetUsage { | |
171 | public: | |
172 | RGWGetUsage_ObjStore() {} | |
173 | ~RGWGetUsage_ObjStore() override {} | |
174 | }; | |
175 | ||
176 | class RGWListBucket_ObjStore : public RGWListBucket { | |
177 | public: | |
178 | RGWListBucket_ObjStore() {} | |
179 | ~RGWListBucket_ObjStore() override {} | |
180 | }; | |
181 | ||
182 | class RGWStatAccount_ObjStore : public RGWStatAccount { | |
183 | public: | |
184 | RGWStatAccount_ObjStore() {} | |
185 | ~RGWStatAccount_ObjStore() override {} | |
186 | }; | |
187 | ||
188 | class RGWStatBucket_ObjStore : public RGWStatBucket { | |
189 | public: | |
190 | RGWStatBucket_ObjStore() {} | |
191 | ~RGWStatBucket_ObjStore() override {} | |
192 | }; | |
193 | ||
194 | class RGWCreateBucket_ObjStore : public RGWCreateBucket { | |
195 | public: | |
196 | RGWCreateBucket_ObjStore() {} | |
197 | ~RGWCreateBucket_ObjStore() override {} | |
198 | }; | |
199 | ||
200 | class RGWDeleteBucket_ObjStore : public RGWDeleteBucket { | |
201 | public: | |
202 | RGWDeleteBucket_ObjStore() {} | |
203 | ~RGWDeleteBucket_ObjStore() override {} | |
204 | }; | |
205 | ||
206 | class RGWPutObj_ObjStore : public RGWPutObj | |
207 | { | |
208 | public: | |
209 | RGWPutObj_ObjStore() {} | |
210 | ~RGWPutObj_ObjStore() override {} | |
211 | ||
212 | int verify_params() override; | |
213 | int get_params() override; | |
214 | int get_data(bufferlist& bl) override; | |
7c673cae FG |
215 | }; |
216 | ||
217 | class RGWPostObj_ObjStore : public RGWPostObj | |
218 | { | |
219 | std::string boundary; | |
220 | ||
221 | public: | |
222 | struct post_part_field { | |
223 | std::string val; | |
224 | std::map<std::string, std::string> params; | |
225 | }; | |
226 | ||
227 | struct post_form_part { | |
228 | std::string name; | |
229 | std::map<std::string, post_part_field, ltstr_nocase> fields; | |
230 | ceph::bufferlist data; | |
231 | }; | |
232 | ||
233 | protected: | |
234 | using parts_collection_t = \ | |
235 | std::map<std::string, post_form_part, const ltstr_nocase>; | |
236 | ||
237 | std::string err_msg; | |
238 | ceph::bufferlist in_data; | |
239 | ||
240 | int read_with_boundary(ceph::bufferlist& bl, | |
241 | uint64_t max, | |
242 | bool check_eol, | |
243 | bool& reached_boundary, | |
244 | bool& done); | |
245 | ||
246 | int read_line(ceph::bufferlist& bl, | |
247 | uint64_t max, | |
248 | bool& reached_boundary, | |
249 | bool& done); | |
250 | ||
251 | int read_data(ceph::bufferlist& bl, | |
252 | uint64_t max, | |
253 | bool& reached_boundary, | |
254 | bool& done); | |
255 | ||
256 | int read_form_part_header(struct post_form_part *part, bool& done); | |
257 | ||
258 | int get_params() override; | |
259 | ||
260 | static int parse_part_field(const std::string& line, | |
261 | std::string& field_name, /* out */ | |
262 | post_part_field& field); /* out */ | |
263 | ||
264 | static void parse_boundary_params(const std::string& params_str, | |
265 | std::string& first, | |
266 | std::map<std::string, std::string>& params); | |
267 | ||
268 | static bool part_str(parts_collection_t& parts, | |
269 | const std::string& name, | |
270 | std::string *val); | |
271 | ||
272 | static std::string get_part_str(parts_collection_t& parts, | |
273 | const std::string& name, | |
274 | const std::string& def_val = std::string()); | |
275 | ||
276 | static bool part_bl(parts_collection_t& parts, | |
277 | const std::string& name, | |
278 | ceph::bufferlist *pbl); | |
279 | ||
280 | public: | |
281 | RGWPostObj_ObjStore() {} | |
282 | ~RGWPostObj_ObjStore() override {} | |
283 | ||
284 | int verify_params() override; | |
285 | }; | |
286 | ||
287 | ||
288 | class RGWPutMetadataAccount_ObjStore : public RGWPutMetadataAccount | |
289 | { | |
290 | public: | |
291 | RGWPutMetadataAccount_ObjStore() {} | |
292 | ~RGWPutMetadataAccount_ObjStore() override {} | |
293 | }; | |
294 | ||
295 | class RGWPutMetadataBucket_ObjStore : public RGWPutMetadataBucket | |
296 | { | |
297 | public: | |
298 | RGWPutMetadataBucket_ObjStore() {} | |
299 | ~RGWPutMetadataBucket_ObjStore() override {} | |
300 | }; | |
301 | ||
302 | class RGWPutMetadataObject_ObjStore : public RGWPutMetadataObject | |
303 | { | |
304 | public: | |
305 | RGWPutMetadataObject_ObjStore() {} | |
306 | ~RGWPutMetadataObject_ObjStore() override {} | |
307 | }; | |
308 | ||
309 | class RGWDeleteObj_ObjStore : public RGWDeleteObj { | |
310 | public: | |
311 | RGWDeleteObj_ObjStore() {} | |
312 | ~RGWDeleteObj_ObjStore() override {} | |
313 | }; | |
314 | ||
315 | class RGWGetCrossDomainPolicy_ObjStore : public RGWGetCrossDomainPolicy { | |
316 | public: | |
317 | RGWGetCrossDomainPolicy_ObjStore() = default; | |
318 | ~RGWGetCrossDomainPolicy_ObjStore() override = default; | |
319 | }; | |
320 | ||
321 | class RGWGetHealthCheck_ObjStore : public RGWGetHealthCheck { | |
322 | public: | |
323 | RGWGetHealthCheck_ObjStore() = default; | |
324 | ~RGWGetHealthCheck_ObjStore() override = default; | |
325 | }; | |
326 | ||
327 | class RGWCopyObj_ObjStore : public RGWCopyObj { | |
328 | public: | |
329 | RGWCopyObj_ObjStore() {} | |
330 | ~RGWCopyObj_ObjStore() override {} | |
331 | }; | |
332 | ||
333 | class RGWGetACLs_ObjStore : public RGWGetACLs { | |
334 | public: | |
335 | RGWGetACLs_ObjStore() {} | |
336 | ~RGWGetACLs_ObjStore() override {} | |
337 | }; | |
338 | ||
339 | class RGWPutACLs_ObjStore : public RGWPutACLs { | |
340 | public: | |
341 | RGWPutACLs_ObjStore() {} | |
342 | ~RGWPutACLs_ObjStore() override {} | |
343 | ||
344 | int get_params() override; | |
345 | }; | |
346 | ||
347 | class RGWGetLC_ObjStore : public RGWGetLC { | |
348 | public: | |
349 | RGWGetLC_ObjStore() {} | |
350 | ~RGWGetLC_ObjStore() override {} | |
351 | }; | |
352 | ||
353 | class RGWPutLC_ObjStore : public RGWPutLC { | |
354 | public: | |
355 | RGWPutLC_ObjStore() {} | |
356 | ~RGWPutLC_ObjStore() override {} | |
357 | ||
358 | int get_params() override; | |
359 | }; | |
360 | ||
361 | class RGWDeleteLC_ObjStore : public RGWDeleteLC { | |
362 | public: | |
363 | RGWDeleteLC_ObjStore() {} | |
364 | ~RGWDeleteLC_ObjStore() override {} | |
365 | ||
366 | }; | |
367 | ||
368 | class RGWGetCORS_ObjStore : public RGWGetCORS { | |
369 | public: | |
370 | RGWGetCORS_ObjStore() {} | |
371 | ~RGWGetCORS_ObjStore() override {} | |
372 | }; | |
373 | ||
374 | class RGWPutCORS_ObjStore : public RGWPutCORS { | |
375 | public: | |
376 | RGWPutCORS_ObjStore() {} | |
377 | ~RGWPutCORS_ObjStore() override {} | |
378 | }; | |
379 | ||
380 | class RGWDeleteCORS_ObjStore : public RGWDeleteCORS { | |
381 | public: | |
382 | RGWDeleteCORS_ObjStore() {} | |
383 | ~RGWDeleteCORS_ObjStore() override {} | |
384 | }; | |
385 | ||
386 | class RGWOptionsCORS_ObjStore : public RGWOptionsCORS { | |
387 | public: | |
388 | RGWOptionsCORS_ObjStore() {} | |
389 | ~RGWOptionsCORS_ObjStore() override {} | |
390 | }; | |
391 | ||
392 | class RGWInitMultipart_ObjStore : public RGWInitMultipart { | |
393 | public: | |
394 | RGWInitMultipart_ObjStore() {} | |
395 | ~RGWInitMultipart_ObjStore() override {} | |
396 | }; | |
397 | ||
398 | class RGWCompleteMultipart_ObjStore : public RGWCompleteMultipart { | |
399 | public: | |
400 | RGWCompleteMultipart_ObjStore() {} | |
401 | ~RGWCompleteMultipart_ObjStore() override {} | |
402 | ||
403 | int get_params() override; | |
404 | }; | |
405 | ||
406 | class RGWAbortMultipart_ObjStore : public RGWAbortMultipart { | |
407 | public: | |
408 | RGWAbortMultipart_ObjStore() {} | |
409 | ~RGWAbortMultipart_ObjStore() override {} | |
410 | }; | |
411 | ||
412 | class RGWListMultipart_ObjStore : public RGWListMultipart { | |
413 | public: | |
414 | RGWListMultipart_ObjStore() {} | |
415 | ~RGWListMultipart_ObjStore() override {} | |
416 | ||
417 | int get_params() override; | |
418 | }; | |
419 | ||
420 | class RGWListBucketMultiparts_ObjStore : public RGWListBucketMultiparts { | |
421 | public: | |
422 | RGWListBucketMultiparts_ObjStore() {} | |
423 | ~RGWListBucketMultiparts_ObjStore() override {} | |
424 | ||
425 | int get_params() override; | |
426 | }; | |
427 | ||
428 | class RGWBulkDelete_ObjStore : public RGWBulkDelete { | |
429 | public: | |
430 | RGWBulkDelete_ObjStore() {} | |
431 | ~RGWBulkDelete_ObjStore() override {} | |
432 | }; | |
433 | ||
434 | class RGWBulkUploadOp_ObjStore : public RGWBulkUploadOp { | |
435 | public: | |
436 | RGWBulkUploadOp_ObjStore() = default; | |
437 | ~RGWBulkUploadOp_ObjStore() = default; | |
438 | }; | |
439 | ||
440 | class RGWDeleteMultiObj_ObjStore : public RGWDeleteMultiObj { | |
441 | public: | |
442 | RGWDeleteMultiObj_ObjStore() {} | |
443 | ~RGWDeleteMultiObj_ObjStore() override {} | |
444 | ||
445 | int get_params() override; | |
446 | }; | |
447 | ||
448 | class RGWInfo_ObjStore : public RGWInfo { | |
449 | public: | |
450 | RGWInfo_ObjStore() = default; | |
451 | ~RGWInfo_ObjStore() override = default; | |
452 | }; | |
453 | ||
454 | class RGWRESTOp : public RGWOp { | |
455 | protected: | |
456 | int http_ret; | |
457 | RGWRESTFlusher flusher; | |
458 | public: | |
459 | RGWRESTOp() : http_ret(0) {} | |
460 | void init(RGWRados *store, struct req_state *s, | |
461 | RGWHandler *dialect_handler) override { | |
462 | RGWOp::init(store, s, dialect_handler); | |
463 | flusher.init(s, this); | |
464 | } | |
465 | void send_response() override; | |
466 | virtual int check_caps(RGWUserCaps& caps) | |
467 | { return -EPERM; } /* should to be implemented! */ | |
468 | int verify_permission() override; | |
469 | }; | |
470 | ||
471 | class RGWHandler_REST : public RGWHandler { | |
472 | protected: | |
473 | ||
474 | virtual bool is_obj_update_op() { return false; } | |
475 | virtual RGWOp *op_get() { return NULL; } | |
476 | virtual RGWOp *op_put() { return NULL; } | |
477 | virtual RGWOp *op_delete() { return NULL; } | |
478 | virtual RGWOp *op_head() { return NULL; } | |
479 | virtual RGWOp *op_post() { return NULL; } | |
480 | virtual RGWOp *op_copy() { return NULL; } | |
481 | virtual RGWOp *op_options() { return NULL; } | |
482 | ||
483 | static int allocate_formatter(struct req_state *s, int default_formatter, | |
484 | bool configurable); | |
485 | public: | |
486 | static constexpr int MAX_BUCKET_NAME_LEN = 255; | |
487 | static constexpr int MAX_OBJ_NAME_LEN = 1024; | |
488 | ||
489 | RGWHandler_REST() {} | |
490 | ~RGWHandler_REST() override {} | |
491 | ||
492 | static int validate_tenant_name(const string& bucket); | |
493 | static int validate_bucket_name(const string& bucket); | |
494 | static int validate_object_name(const string& object); | |
495 | ||
496 | int init_permissions(RGWOp* op) override; | |
497 | int read_permissions(RGWOp* op) override; | |
498 | ||
499 | virtual RGWOp* get_op(RGWRados* store); | |
500 | virtual void put_op(RGWOp* op); | |
501 | }; | |
502 | ||
503 | class RGWHandler_REST_SWIFT; | |
504 | class RGWHandler_SWIFT_Auth; | |
505 | class RGWHandler_REST_S3; | |
506 | ||
507 | namespace rgw { | |
508 | namespace auth { | |
509 | ||
510 | class StrategyRegistry; | |
511 | ||
512 | } | |
513 | } | |
514 | ||
515 | class RGWRESTMgr { | |
516 | bool should_log; | |
517 | ||
518 | protected: | |
519 | std::map<std::string, RGWRESTMgr*> resource_mgrs; | |
520 | std::multimap<size_t, std::string> resources_by_size; | |
521 | RGWRESTMgr* default_mgr; | |
522 | ||
523 | virtual RGWRESTMgr* get_resource_mgr(struct req_state* s, | |
524 | const std::string& uri, | |
525 | std::string* out_uri); | |
526 | ||
527 | virtual RGWRESTMgr* get_resource_mgr_as_default(struct req_state* const s, | |
528 | const std::string& uri, | |
529 | std::string* our_uri) { | |
530 | return this; | |
531 | } | |
532 | ||
533 | public: | |
534 | RGWRESTMgr() | |
535 | : should_log(false), | |
536 | default_mgr(nullptr) { | |
537 | } | |
538 | virtual ~RGWRESTMgr(); | |
539 | ||
540 | void register_resource(std::string resource, RGWRESTMgr* mgr); | |
541 | void register_default_mgr(RGWRESTMgr* mgr); | |
542 | ||
543 | virtual RGWRESTMgr* get_manager(struct req_state* const s, | |
544 | /* Prefix to be concatenated with @uri | |
545 | * during the lookup. */ | |
546 | const std::string& frontend_prefix, | |
547 | const std::string& uri, | |
548 | std::string* out_uri) final { | |
549 | return get_resource_mgr(s, frontend_prefix + uri, out_uri); | |
550 | } | |
551 | ||
552 | virtual RGWHandler_REST* get_handler( | |
553 | struct req_state* const s, | |
554 | const rgw::auth::StrategyRegistry& auth_registry, | |
555 | const std::string& frontend_prefix | |
556 | ) { | |
557 | return nullptr; | |
558 | } | |
559 | ||
560 | virtual void put_handler(RGWHandler_REST* const handler) { | |
561 | delete handler; | |
562 | } | |
563 | ||
564 | void set_logging(bool _should_log) { | |
565 | should_log = _should_log; | |
566 | } | |
567 | ||
568 | bool get_logging() const { | |
569 | return should_log; | |
570 | } | |
571 | }; | |
572 | ||
573 | class RGWLibIO; | |
574 | class RGWRestfulIO; | |
575 | ||
576 | class RGWREST { | |
577 | using x_header = basic_sstring<char, uint16_t, 32>; | |
578 | boost::container::flat_set<x_header> x_headers; | |
579 | RGWRESTMgr mgr; | |
580 | ||
581 | static int preprocess(struct req_state *s, rgw::io::BasicClient* rio); | |
582 | public: | |
583 | RGWREST() {} | |
584 | RGWHandler_REST *get_handler(RGWRados *store, | |
585 | struct req_state *s, | |
586 | const rgw::auth::StrategyRegistry& auth_registry, | |
587 | const std::string& frontend_prefix, | |
588 | RGWRestfulIO *rio, | |
589 | RGWRESTMgr **pmgr, | |
590 | int *init_error); | |
591 | #if 0 | |
592 | RGWHandler *get_handler(RGWRados *store, struct req_state *s, | |
593 | RGWLibIO *io, RGWRESTMgr **pmgr, | |
594 | int *init_error); | |
595 | #endif | |
596 | ||
597 | void put_handler(RGWHandler_REST *handler) { | |
598 | mgr.put_handler(handler); | |
599 | } | |
600 | ||
601 | void register_resource(string resource, RGWRESTMgr *m, | |
602 | bool register_empty = false) { | |
603 | if (!register_empty && resource.empty()) | |
604 | return; | |
605 | ||
606 | mgr.register_resource(resource, m); | |
607 | } | |
608 | ||
609 | void register_default_mgr(RGWRESTMgr *m) { | |
610 | mgr.register_default_mgr(m); | |
611 | } | |
612 | ||
613 | void register_x_headers(const std::string& headers); | |
614 | ||
615 | bool log_x_headers(void) { | |
616 | return (x_headers.size() > 0); | |
617 | } | |
618 | ||
619 | bool log_x_header(const std::string& header) { | |
620 | return (x_headers.find(header) != x_headers.end()); | |
621 | } | |
622 | }; | |
623 | ||
624 | static constexpr int64_t NO_CONTENT_LENGTH = -1; | |
625 | static constexpr int64_t CHUNKED_TRANSFER_ENCODING = -2; | |
626 | ||
7c673cae FG |
627 | extern void dump_errno(int http_ret, string& out); |
628 | extern void dump_errno(const struct rgw_err &err, string& out); | |
629 | extern void dump_errno(struct req_state *s); | |
630 | extern void dump_errno(struct req_state *s, int http_ret); | |
631 | extern void end_header(struct req_state *s, | |
632 | RGWOp* op = nullptr, | |
633 | const char *content_type = nullptr, | |
634 | const int64_t proposed_content_length = | |
635 | NO_CONTENT_LENGTH, | |
636 | bool force_content_type = false, | |
637 | bool force_no_error = false); | |
638 | extern void dump_start(struct req_state *s); | |
639 | extern void list_all_buckets_start(struct req_state *s); | |
640 | extern void dump_owner(struct req_state *s, const rgw_user& id, string& name, | |
641 | const char *section = NULL); | |
642 | extern void dump_header(struct req_state* s, | |
643 | const boost::string_ref& name, | |
644 | const boost::string_ref& val); | |
645 | extern void dump_header(struct req_state* s, | |
646 | const boost::string_ref& name, | |
647 | ceph::buffer::list& bl); | |
648 | extern void dump_header(struct req_state* s, | |
649 | const boost::string_ref& name, | |
650 | long long val); | |
651 | extern void dump_header(struct req_state* s, | |
652 | const boost::string_ref& name, | |
653 | const utime_t& val); | |
654 | template <class... Args> | |
655 | static inline void dump_header_prefixed(struct req_state* s, | |
656 | const boost::string_ref& name_prefix, | |
657 | const boost::string_ref& name, | |
658 | Args&&... args) { | |
659 | char full_name_buf[name_prefix.size() + name.size() + 1]; | |
660 | const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s", | |
661 | static_cast<int>(name_prefix.length()), | |
662 | name_prefix.data(), | |
663 | static_cast<int>(name.length()), | |
664 | name.data()); | |
665 | boost::string_ref full_name(full_name_buf, len); | |
666 | return dump_header(s, std::move(full_name), std::forward<Args>(args)...); | |
667 | } | |
668 | ||
669 | template <class... Args> | |
670 | static inline void dump_header_quoted(struct req_state* s, | |
671 | const boost::string_ref& name, | |
672 | const boost::string_ref& val) { | |
673 | /* We need two extra bytes for quotes. */ | |
674 | char qvalbuf[val.size() + 2 + 1]; | |
675 | const auto len = snprintf(qvalbuf, sizeof(qvalbuf), "\"%.*s\"", | |
676 | static_cast<int>(val.length()), val.data()); | |
677 | return dump_header(s, name, boost::string_ref(qvalbuf, len)); | |
678 | } | |
679 | ||
680 | template <class ValueT> | |
681 | static inline void dump_header_if_nonempty(struct req_state* s, | |
682 | const boost::string_ref& name, | |
683 | const ValueT& value) { | |
684 | if (name.length() > 0 && value.length() > 0) { | |
685 | return dump_header(s, name, value); | |
686 | } | |
687 | } | |
688 | ||
689 | extern void dump_content_length(struct req_state *s, uint64_t len); | |
31f18b77 | 690 | extern int64_t parse_content_length(const char *content_length); |
7c673cae FG |
691 | extern void dump_etag(struct req_state *s, |
692 | const boost::string_ref& etag, | |
693 | bool quoted = false); | |
694 | extern void dump_etag(struct req_state *s, | |
695 | ceph::buffer::list& bl_etag, | |
696 | bool quoted = false); | |
697 | extern void dump_epoch_header(struct req_state *s, const char *name, real_time t); | |
698 | extern void dump_time_header(struct req_state *s, const char *name, real_time t); | |
699 | extern void dump_last_modified(struct req_state *s, real_time t); | |
700 | extern void abort_early(struct req_state* s, RGWOp* op, int err, | |
701 | RGWHandler* handler); | |
702 | extern void dump_range(struct req_state* s, uint64_t ofs, uint64_t end, | |
703 | uint64_t total_size); | |
704 | extern void dump_continue(struct req_state *s); | |
705 | extern void list_all_buckets_end(struct req_state *s); | |
706 | extern void dump_time(struct req_state *s, const char *name, real_time *t); | |
707 | extern std::string dump_time_to_str(const real_time& t); | |
708 | extern void dump_bucket_from_state(struct req_state *s); | |
709 | extern void dump_uri_from_state(struct req_state *s); | |
710 | extern void dump_redirect(struct req_state *s, const string& redirect); | |
711 | extern bool is_valid_url(const char *url); | |
712 | extern void dump_access_control(struct req_state *s, const char *origin, | |
713 | const char *meth, | |
714 | const char *hdr, const char *exp_hdr, | |
715 | uint32_t max_age); | |
716 | extern void dump_access_control(req_state *s, RGWOp *op); | |
717 | ||
718 | extern int dump_body(struct req_state* s, const char* buf, size_t len); | |
719 | extern int dump_body(struct req_state* s, /* const */ ceph::buffer::list& bl); | |
720 | extern int dump_body(struct req_state* s, const std::string& str); | |
721 | ||
722 | extern int recv_body(struct req_state* s, char* buf, size_t max); | |
723 | ||
724 | #endif /* CEPH_RGW_REST_H */ |