From: Yehuda Sadeh Date: Wed, 23 Oct 2013 01:11:23 +0000 (-0700) Subject: rgw: support for mongoose keepalive X-Git-Tag: v0.75~60^2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d0bd7f352391da94527e714d2bb64314b15313a8;p=ceph.git rgw: support for mongoose keepalive Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_client_io.cc b/src/rgw/rgw_client_io.cc index 46385f41f332..41cd6b98b18a 100644 --- a/src/rgw/rgw_client_io.cc +++ b/src/rgw/rgw_client_io.cc @@ -57,3 +57,4 @@ int RGWClientIO::read(char *buf, int max, int *actual) return 0; } + diff --git a/src/rgw/rgw_client_io.h b/src/rgw/rgw_client_io.h index 4f0168a8cc2e..64705fd20cbd 100644 --- a/src/rgw/rgw_client_io.h +++ b/src/rgw/rgw_client_io.h @@ -37,6 +37,8 @@ public: virtual int send_status(const char *status, const char *status_name) = 0; virtual int send_100_continue() = 0; virtual int complete_header() = 0; + virtual int complete_request() = 0; + virtual int send_content_length(uint64_t len) = 0; RGWEnv& get_env() { return env; } diff --git a/src/rgw/rgw_env.cc b/src/rgw/rgw_env.cc index 0628dffbde4a..59542efc5a7f 100644 --- a/src/rgw/rgw_env.cc +++ b/src/rgw/rgw_env.cc @@ -27,7 +27,7 @@ void RGWEnv::set(const char *name, const char *val) val = ""; env_map[name] = val; - dout(0) << "RGWEnv::set(): " << name << ": " << val << dendl; + dout(20) << "RGWEnv::set(): " << name << ": " << val << dendl; } void RGWEnv::init(CephContext *cct, char **envp) diff --git a/src/rgw/rgw_fcgi.cc b/src/rgw/rgw_fcgi.cc index e653ee6fc0de..4b24dabe5568 100644 --- a/src/rgw/rgw_fcgi.cc +++ b/src/rgw/rgw_fcgi.cc @@ -44,6 +44,13 @@ int RGWFCGX::send_100_continue() return r; } +int RGWFCGX::send_content_length(uint64_t len) +{ + char buf[21]; + snprintf(buf, sizeof(buf), "%"PRIu64, len); + return print("Content-Length: %s\n", buf); +} + int RGWFCGX::complete_header() { return print("\r\n"); diff --git a/src/rgw/rgw_fcgi.h b/src/rgw/rgw_fcgi.h index 16d9fb6ca306..fabc77a0f1ba 100644 --- a/src/rgw/rgw_fcgi.h +++ b/src/rgw/rgw_fcgi.h @@ -18,6 +18,8 @@ protected: int send_status(const char *status, const char *status_name); int send_100_continue(); int complete_header(); + int complete_request() { return 0; } + int send_content_length(uint64_t len); public: RGWFCGX(FCGX_Request *_fcgx) : fcgx(_fcgx) {} void flush(); diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index d8d98456106e..2343bd61b936 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -540,6 +540,10 @@ static int mongoose_callback(struct mg_event *event) { op->execute(); op->complete(); done: + ret = client_io.complete_request(); + if (ret < 0) { + dout(0) << "ERROR: client_io.complete_request() returned " << ret << dendl; + } if (should_log) { rgw_log_op(store, s, (op ? op->name() : "unknown"), olog); } @@ -727,7 +731,7 @@ int main(int argc, const char **argv) } struct mg_context *ctx; - const char *options[] = {"listening_ports", "8080", NULL}; + const char *options[] = {"listening_ports", "8080", "enable_keep_alive", "yes", NULL}; RGWProcessEnv pe = { store, &rest, olog }; diff --git a/src/rgw/rgw_mongoose.cc b/src/rgw/rgw_mongoose.cc index cbbc19226f87..20b6b8b2a6d4 100644 --- a/src/rgw/rgw_mongoose.cc +++ b/src/rgw/rgw_mongoose.cc @@ -9,15 +9,18 @@ int RGWMongoose::write_data(const char *buf, int len) { - if (!sent_header) { + if (!header_done) { header_data.append(buf, len); return 0; } - dout(0) << buf << dendl; + if (!sent_header) { + data.append(buf, len); + return 0; + } return mg_write(event->conn, buf, len); } -RGWMongoose::RGWMongoose(mg_event *_event) : event(_event), sent_header(false) { +RGWMongoose::RGWMongoose(mg_event *_event) : event(_event), header_done(false), sent_header(false), has_content_length(false) { } int RGWMongoose::read_data(char *buf, int len) @@ -29,6 +32,29 @@ void RGWMongoose::flush() { } +int RGWMongoose::complete_request() +{ + if (!sent_header) { + if (!has_content_length) { + header_done = false; /* let's go back to writing the header */ + int r = send_content_length(data.length()); + if (r < 0) + return r; + } + + complete_header(); + } + + if (data.length()) { + int r = write_data(data.c_str(), data.length()); + if (r < 0) + return r; + data.clear(); + } + + return 0; +} + void RGWMongoose::init_env(CephContext *cct) { env.init(cct); @@ -104,9 +130,23 @@ int RGWMongoose::send_100_continue() int RGWMongoose::complete_header() { + header_done = true; + + if (!has_content_length) { + return 0; + } + header_data.append("\r\n"); sent_header = true; return write_data(header_data.c_str(), header_data.length()); } + +int RGWMongoose::send_content_length(uint64_t len) +{ + has_content_length = true; + char buf[21]; + snprintf(buf, sizeof(buf), "%"PRIu64, len); + return print("Content-Length: %s\n", buf); +} diff --git a/src/rgw/rgw_mongoose.h b/src/rgw/rgw_mongoose.h index 33787d0e6132..9454d90a0dab 100644 --- a/src/rgw/rgw_mongoose.h +++ b/src/rgw/rgw_mongoose.h @@ -13,10 +13,13 @@ class RGWMongoose : public RGWClientIO mg_event *event; bufferlist header_data; + bufferlist data; + bool header_done; bool sent_header; + bool has_content_length; -protected: +public: void init_env(CephContext *cct); int write_data(const char *buf, int len); @@ -25,8 +28,9 @@ protected: int send_status(const char *status, const char *status_name); int send_100_continue(); int complete_header(); + int complete_request(); + int send_content_length(uint64_t len); -public: RGWMongoose(mg_event *_event); void flush(); }; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 41ee2e88f9b9..ab6f925dbc91 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -66,7 +66,9 @@ public: virtual int verify_op_mask(); virtual void execute() = 0; virtual void send_response() {} - virtual void complete() { send_response(); } + virtual void complete() { + send_response(); + } virtual const string name() = 0; virtual uint32_t op_mask() { return 0; } diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index f05728ec9fdb..a18f28ecde45 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -236,9 +236,7 @@ void dump_errno(struct req_state *s, int err) void dump_content_length(struct req_state *s, uint64_t len) { - char buf[21]; - snprintf(buf, sizeof(buf), "%"PRIu64, len); - int r = s->cio->print("Content-Length: %s\n", buf); + int r = s->cio->send_content_length(len); if (r < 0) { ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl; } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 12bd377d8a06..d6cc73cd911c 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1157,7 +1157,9 @@ done: s->err.message = err_msg; set_req_state_err(s, ret); dump_errno(s); - dump_content_length(s, s->formatter->get_len()); + if (ret >= 0) { + dump_content_length(s, s->formatter->get_len()); + } end_header(s, this); if (ret != STATUS_CREATED) return;