summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-10-22 18:11:23 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-10-22 18:11:23 -0700
commit455fcfc68f4201ed2451500392e038ba87db8a90 (patch)
tree4495b758d50dbdc71586b19f9f2489d096377b0b
parent5b6519c51d64fcaffa5728b69d65ec055df81cac (diff)
downloadceph-455fcfc68f4201ed2451500392e038ba87db8a90.tar.gz
rgw: support for mongoose keepalive
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_client_io.cc1
-rw-r--r--src/rgw/rgw_client_io.h2
-rw-r--r--src/rgw/rgw_env.cc2
-rw-r--r--src/rgw/rgw_fcgi.cc7
-rw-r--r--src/rgw/rgw_fcgi.h2
-rw-r--r--src/rgw/rgw_main.cc6
-rw-r--r--src/rgw/rgw_mongoose.cc46
-rw-r--r--src/rgw/rgw_mongoose.h8
-rw-r--r--src/rgw/rgw_op.h4
-rw-r--r--src/rgw/rgw_rest.cc4
-rw-r--r--src/rgw/rgw_rest_s3.cc4
11 files changed, 74 insertions, 12 deletions
diff --git a/src/rgw/rgw_client_io.cc b/src/rgw/rgw_client_io.cc
index 46385f41f33..41cd6b98b18 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 4f0168a8cc2..64705fd20cb 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 0628dffbde4..59542efc5a7 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 e653ee6fc0d..4b24dabe556 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 16d9fb6ca30..fabc77a0f1b 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 d8d98456106..2343bd61b93 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 cbbc19226f8..20b6b8b2a6d 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 33787d0e613..9454d90a0da 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 eee5ea99065..c4fb563c073 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 0924ebbff55..d264c46b0ad 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 83874dd42c4..686ea6d0e3c 100644
--- a/src/rgw/rgw_rest_s3.cc
+++ b/src/rgw/rgw_rest_s3.cc
@@ -1211,7 +1211,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;