parse_date(start_date, &start_epoch);
parse_date(end_date, &end_epoch);
+ RGWStreamFlusher f(formatter, cout);
+
int ret = RGWUsage::show(rgwstore, user_id, start_epoch, end_epoch,
show_log_entries, show_log_sum, &categories,
- formatter);
+ f);
if (ret < 0) {
cerr << "ERROR: failed to show usage" << std::endl;
return 1;
size_t min_stack_level;
};
+class RGWFormatterFlusher {
+protected:
+ Formatter *formatter;
+ bool flushed;
+ bool started;
+ virtual void do_flush() = 0;
+ virtual void do_start(int ret) {}
+ void set_formatter(Formatter *f) {
+ formatter = f;
+ }
+public:
+ RGWFormatterFlusher(Formatter *f) : formatter(f), flushed(false), started(false) {}
+ virtual ~RGWFormatterFlusher() {}
+
+ void flush() {
+ do_flush();
+ flushed = true;
+ }
+
+ virtual void start(int client_ret) {
+ if (!started)
+ do_start(client_ret);
+ started = true;
+ }
+
+ Formatter *get_formatter() { return formatter; }
+ bool did_flush() { return flushed; }
+ bool did_start() { return started; }
+};
+
+class RGWStreamFlusher : public RGWFormatterFlusher {
+ ostream& os;
+protected:
+ virtual void do_flush() {
+ formatter->flush(os);
+ }
+public:
+ RGWStreamFlusher(Formatter *f, ostream& _os) : RGWFormatterFlusher(f), os(_os) {}
+};
+
#endif
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
-static const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
+static inline const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
{
for (int i = 0; i < len; ++i, ++errs) {
if (err_no == errs->err_no)
return 0;
}
+void RGWRESTFlusher::do_start(int ret)
+{
+ set_req_state_err(s, ret); /* no going back from here */
+ dump_errno(s);
+ dump_start(s);
+ end_header(s);
+ rgw_flush_formatter_and_reset(s, s->formatter);
+}
+
+void RGWRESTFlusher::do_flush()
+{
+ rgw_flush_formatter(s, s->formatter);
+}
int RGWPutObj_ObjStore::verify_params()
{
return ret;
}
+
+void RGWRESTOp::send_response()
+{
+ if (!flusher.did_start()) {
+ set_req_state_err(s, http_ret);
+ dump_errno(s);
+ end_header(s);
+ }
+ flusher.flush();
+}
+
static void line_unfold(const char *line, string& sdest)
{
char dest[strlen(line) + 1];
#define TIME_BUF_SIZE 128
#include "rgw_op.h"
+#include "rgw_formats.h"
extern void rgw_flush_formatter_and_reset(struct req_state *s,
ceph::Formatter *formatter);
extern void rgw_flush_formatter(struct req_state *s,
ceph::Formatter *formatter);
+
+class RGWRESTFlusher : public RGWFormatterFlusher {
+ struct req_state *s;
+protected:
+ virtual void do_flush();
+ virtual void do_start(int ret);
+public:
+ RGWRESTFlusher(struct req_state *_s) : RGWFormatterFlusher(_s->formatter), s(_s) {}
+ RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL) {}
+
+ void init(struct req_state *_s) {
+ s = _s;
+ set_formatter(s->formatter);
+ }
+};
+
class RGWClientIO;
class RGWGetObj_ObjStore : public RGWGetObj
int get_params();
};
+class RGWRESTOp : public RGWOp {
+protected:
+ int http_ret;
+ RGWRESTFlusher flusher;
+public:
+ RGWRESTOp() : http_ret(0) {}
+ virtual void init(struct req_state *s, RGWHandler *dialect_handler) {
+ RGWOp::init(s, dialect_handler);
+ flusher.init(s);
+ }
+ virtual void send_response();
+};
+
class RGWHandler_ObjStore : public RGWHandler {
protected:
virtual bool is_obj_update_op() { return false; }
* verify that a signed request comes from the keyholder
* by checking the signature against our locally-computed version
*/
-int RGWHandler_ObjStore_S3::authorize()
+int RGW_Auth_S3::authorize(struct req_state *s)
{
bool qsr = false;
string auth_id;
return 0;
}
+int RGWHandler_Auth_S3::init(struct req_state *state, RGWClientIO *cio)
+{
+ int ret = RGWHandler_ObjStore_S3::init_from_header(state);
+ if (ret < 0)
+ return ret;
+
+ return RGWHandler_ObjStore::init(state, cio);
+}
+
RGWHandler *RGWRESTMgr_S3::get_handler(struct req_state *s)
{
int ret = RGWHandler_ObjStore_S3::init_from_header(s);
void end_response();
};
+class RGW_Auth_S3 {
+public:
+ static int authorize(struct req_state *s);
+};
+
+class RGWHandler_Auth_S3 : public RGWHandler_ObjStore {
+ friend class RGWRESTMgr_S3;
+public:
+ RGWHandler_Auth_S3() : RGWHandler_ObjStore() {}
+ virtual ~RGWHandler_Auth_S3() {}
+
+ virtual int validate_bucket_name(const string& bucket) { return 0; }
+ virtual int validate_object_name(const string& bucket) { return 0; }
+
+ virtual int init(struct req_state *state, RGWClientIO *cio);
+ virtual int authorize() {
+ return RGW_Auth_S3::authorize(s);
+ }
+};
+
class RGWHandler_ObjStore_S3 : public RGWHandler_ObjStore {
friend class RGWRESTMgr_S3;
public:
int validate_bucket_name(const string& bucket);
virtual int init(struct req_state *state, RGWClientIO *cio);
- int authorize();
+ virtual int authorize() {
+ return RGW_Auth_S3::authorize(s);
+ }
};
class RGWHandler_ObjStore_Service_S3 : public RGWHandler_ObjStore_S3 {
#include "rgw_usage.h"
#include "rgw_rest_usage.h"
-class RGWOp_Usage : public RGWOp {
+class RGWOp_Usage : public RGWRESTOp {
public:
RGWOp_Usage() {}
void RGWOp_Usage::execute() {
map<std::string, bool> categories;
- int ret = RGWUsage::show(rgwstore, s->user.user_id, 0, (uint64_t)-1, true, true, &categories, s->formatter);
- if (ret)
- set_req_state_err(s, ret);
- dump_errno(s);
- dump_start(s);
-
- rgw_flush_formatter_and_reset(s, s->formatter);
+ http_ret = RGWUsage::show(rgwstore, s->user.user_id, 0, (uint64_t)-1, true, true, &categories, flusher);
}
RGWOp *RGWHandler_Usage::op_get()
#include "rgw_rest_s3.h"
-class RGWHandler_Usage : public RGWHandler_ObjStore_S3 {
+class RGWHandler_Usage : public RGWHandler_Auth_S3 {
protected:
RGWOp *op_get();
// RGWOp *op_delete();
virtual ~RGWRESTMgr_Usage() {}
RGWHandler *get_handler(struct req_state *s) {
- int ret = RGWHandler_ObjStore_S3::init_from_header(s);
- if (ret < 0)
- return NULL;
return new RGWHandler_Usage;
}
};
#include "rgw_rados.h"
#include "rgw_usage.h"
+#include "rgw_formats.h"
using namespace std;
int RGWUsage::show(RGWRados *store, string& uid, uint64_t start_epoch,
uint64_t end_epoch, bool show_log_entries, bool show_log_sum,
map<string, bool> *categories,
- ceph::Formatter *formatter)
+ RGWFormatterFlusher& flusher)
{
uint32_t max_entries = 1000;
bool is_truncated = true;
RGWUsageIter usage_iter;
+ Formatter *formatter = flusher.get_formatter();
map<rgw_user_bucket, rgw_usage_log_entry> usage;
+ flusher.start(0);
+
formatter->open_object_section("usage");
if (show_log_entries) {
formatter->open_array_section("entries");
formatter->dump_int("epoch", entry.epoch);
dump_usage_categories_info(formatter, entry, categories);
formatter->close_section(); // bucket
- formatter->flush(cout);
+ flusher.flush();
}
summary_map[ub.user].aggregate(entry, categories);
formatter->close_section(); // user
- formatter->flush(cout);
+ flusher.flush();
}
formatter->close_section(); // summary
}
formatter->close_section(); // usage
- formatter->flush(cout);
+ flusher.flush();
return 0;
}
#include <map>
#include "common/Formatter.h"
+#include "rgw_formats.h"
class RGWRados;
static int show(RGWRados *store, std::string& uid, uint64_t start_epoch,
uint64_t end_epoch, bool show_log_entries, bool show_log_sum,
std::map<std::string, bool> *categories,
- ceph::Formatter *formatter);
+ RGWFormatterFlusher& flusher);
static int trim(RGWRados *store, std::string& uid, uint64_t start_epoch,
uint64_t end_epoch);