]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: support for mongoose keepalive
authorYehuda Sadeh <yehuda@inktank.com>
Wed, 23 Oct 2013 01:11:23 +0000 (18:11 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Tue, 5 Nov 2013 04:28:13 +0000 (20:28 -0800)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_client_io.cc
src/rgw/rgw_client_io.h
src/rgw/rgw_env.cc
src/rgw/rgw_fcgi.cc
src/rgw/rgw_fcgi.h
src/rgw/rgw_main.cc
src/rgw/rgw_mongoose.cc
src/rgw/rgw_mongoose.h
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc

index 46385f41f3328ec2300e780b228a6f4cbdca5d67..41cd6b98b18aed101269ea15216a89040f9e2eec 100644 (file)
@@ -57,3 +57,4 @@ int RGWClientIO::read(char *buf, int max, int *actual)
 
   return 0;
 }
+
index 4f0168a8cc2e7cc20663a8d48493921aaa6ef222..64705fd20cbda29bddd305cf5ca032632ffd42dd 100644 (file)
@@ -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; }
 
index 0628dffbde4a72e08176f46db137caf0e94e9c2f..59542efc5a7f640bf62bffbdaff04fc59d95f901 100644 (file)
@@ -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)
index e653ee6fc0de777f8fbfd993b4ac66c54e03b4fa..4b24dabe5568a790b1dc1a15829bf6d458e665ee 100644 (file)
@@ -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");
index 16d9fb6ca306fb0a83dbb019c30b266f8e47108c..fabc77a0f1bad4f9185f4e793c5dac4016828d4f 100644 (file)
@@ -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();
index d8d98456106e17522c63b79c72f96f2dea5099a3..2343bd61b936d21c5f1587750ae6e1a6b799987f 100644 (file)
@@ -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 };
 
index cbbc19226f87014e0e4295c1f7113008e52a81fe..20b6b8b2a6d4d47eda0dde5788631a6e2bf9cbab 100644 (file)
@@ -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);
+}
index 33787d0e61327e2619ab52fdff66856a17bdacf3..9454d90a0dabbe5332612de560a5e36a59bcdc27 100644 (file)
@@ -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();
 };
index 41ee2e88f9b9dc8855d0b9bbe2fd3eb8d2e705e1..ab6f925dbc919b2623e93f1aebdecfea115fd68c 100644 (file)
@@ -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; }
index f05728ec9fdb445685756cf3ebdd15b42dec36fa..a18f28ecde457160f891eb91ef856a2c0d8c2620 100644 (file)
@@ -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;
   }
index 12bd377d8a0647a6391ebce4e4fede041abdeaea..d6cc73cd911cbad79c0f968b36d8b7893091a232 100644 (file)
@@ -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;