Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_rest.h
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 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
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;
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
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
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);
665
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
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
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);
720 extern int64_t parse_content_length(const char *content_length);
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 */