]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rgw/rgw_civetweb.cc
update sources to 12.2.7
[ceph.git] / ceph / src / rgw / rgw_civetweb.cc
index 93a8a030ac007d660ad664118437688d7c8c0995..c3f585cfc21863624d3212eace00d358980578aa 100644 (file)
@@ -33,6 +33,7 @@ RGWCivetWeb::RGWCivetWeb(mg_connection* const conn)
   : conn(conn),
     explicit_keepalive(false),
     explicit_conn_close(false),
+    got_eof_on_read(false),
     txbuf(*this)
 {
     sockaddr *lsa = mg_get_local_addr(conn);
@@ -50,11 +51,21 @@ RGWCivetWeb::RGWCivetWeb(mg_connection* const conn)
 
 size_t RGWCivetWeb::read_data(char *buf, size_t len)
 {
-  const int ret = mg_read(conn, buf, len);
-  if (ret < 0) {
-    throw rgw::io::Exception(EIO, std::system_category());
+  int c, ret;
+  if (got_eof_on_read) {
+    return 0;
+  }
+  for (c = 0; c < len; c += ret) {
+    ret = mg_read(conn, buf+c, len-c);
+    if (ret < 0) {
+      throw rgw::io::Exception(EIO, std::system_category());
+    }
+    if (!ret) {
+      got_eof_on_read = true;
+      break;
+    }
   }
-  return ret;
+  return c;
 }
 
 void RGWCivetWeb::flush()
@@ -67,17 +78,24 @@ size_t RGWCivetWeb::complete_request()
   return 0;
 }
 
-void RGWCivetWeb::init_env(CephContext *cct)
+int RGWCivetWeb::init_env(CephContext *cct)
 {
   env.init(cct);
   const struct mg_request_info* info = mg_get_request_info(conn);
 
   if (! info) {
-    return;
+    // request info is NULL; we have no info about the connection
+    return -EINVAL;
   }
 
   for (int i = 0; i < info->num_headers; i++) {
     const struct mg_request_info::mg_header* header = &info->http_headers[i];
+
+    if (header->name == nullptr || header->value==nullptr) {
+      lderr(cct) << "client supplied malformatted headers" << dendl;
+      return -EINVAL;
+    }
+
     const boost::string_ref name(header->name);
     const auto& value = header->value;
 
@@ -110,7 +128,9 @@ void RGWCivetWeb::init_env(CephContext *cct)
     env.set(buf, value);
   }
 
+  env.set("REMOTE_ADDR", info->remote_addr);
   env.set("REQUEST_METHOD", info->request_method);
+  env.set("HTTP_VERSION", info->http_version);
   env.set("REQUEST_URI", info->request_uri); // get the full uri, we anyway handle abs uris later
   env.set("SCRIPT_URI", info->uri); /* FIXME */
   if (info->query_string) {
@@ -128,6 +148,7 @@ void RGWCivetWeb::init_env(CephContext *cct)
   if (info->is_ssl) {
     env.set("SERVER_PORT_SECURE", port_buf);
   }
+  return 0;
 }
 
 size_t RGWCivetWeb::send_status(int status, const char *status_name)