]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix the handling of rgw_swift_url_prefix.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Thu, 23 Jun 2016 13:43:49 +0000 (15:43 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Thu, 14 Jul 2016 13:46:24 +0000 (15:46 +0200)
This patch fixes to the support for placing the Swift API in the root
of URL hierarchy. Unfortunately, the whole concept exhibits a severe side
effect: inability to deploy RadosGW in multi-site configuration.

The sole reason behind this fix is the fact we claimed in documentation
that the feature is available.

Fixes: http://tracker.ceph.com/issues/16673
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
doc/radosgw/config-ref.rst
src/rgw/rgw_main.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h

index 8ddecbb5647197dd472137a5363346d3b36d7ef4..6c20f264a2211c1a2947030f52e93636f02301c1 100644 (file)
@@ -796,6 +796,9 @@ Swift Settings
               on the same host. For compatibility, setting this configuration
               variable to empty causes the default "/swift" to be used.
               Use explicit prefix "/" to start StorageURL at the root.
+              WARNING: setting this option to "/" will NOT work if S3 API is
+              enabled. From the other side disabling S3 will make impossible
+              to deploy RadosGW in the multi-site configuration!
 :Default: ``swift``
 :Example: "/swift-testing"
 
index 85c044ae27536b385adcd6402a7807bf4cee3e2b..b73701ce70b29e0cdc8512a8a73909f049726e54 100644 (file)
@@ -342,13 +342,32 @@ int main(int argc, const char **argv)
   }
 
   // S3 website mode is a specialization of S3
-  bool s3website_enabled = apis_map.count("s3website") > 0;
-  if (apis_map.count("s3") > 0 || s3website_enabled)
-    rest.register_default_mgr(set_logging(new RGWRESTMgr_S3(s3website_enabled)));
+  const bool s3website_enabled = apis_map.count("s3website") > 0;
+  // Swift API entrypoint could placed in the root instead of S3
+  const bool swift_at_root = g_conf->rgw_swift_url_prefix == "/";
+  if (apis_map.count("s3") > 0 || s3website_enabled) {
+    if (! swift_at_root) {
+      rest.register_default_mgr(set_logging(new RGWRESTMgr_S3(s3website_enabled)));
+    } else {
+      derr << "Cannot have the S3 or S3 Website enabled together with "
+           << "Swift API placed in the root of hierarchy" << dendl;
+      return EINVAL;
+    }
+  }
 
   if (apis_map.count("swift") > 0) {
-    rest.register_resource(g_conf->rgw_swift_url_prefix,
-               set_logging(new RGWRESTMgr_SWIFT));
+    if (! swift_at_root) {
+      rest.register_resource(g_conf->rgw_swift_url_prefix,
+                             set_logging(new RGWRESTMgr_SWIFT));
+    } else {
+      if (store->get_zonegroup().zones.size() > 1) {
+        derr << "Placing Swift API in the root of URL hierarchy while running"
+             << " multi-site configuration requires another instance of RadosGW"
+             << " with S3 API enabled!" << dendl;
+      }
+
+      rest.register_default_mgr(set_logging(new RGWRESTMgr_SWIFT));
+    }
   }
 
   if (apis_map.count("swift_auth") > 0)
index 655bbd290e59e7ed9cdda698cd147810db4a51b1..848e99efd854efb4129136b0ef605c749430316b 100644 (file)
@@ -1629,8 +1629,9 @@ RGWRESTMgr *RGWRESTMgr::get_resource_mgr(struct req_state *s, const string& uri,
     }
   }
 
-  if (default_mgr)
-    return default_mgr;
+  if (default_mgr) {
+    return default_mgr->get_resource_mgr_as_default(s, uri, out_uri);
+  }
 
   return this;
 }
index 3e23945fb2d84a728b37d22170f3b14e20443023..79d695d12d0610da398128319c74c16f0c0cf554 100644 (file)
@@ -418,6 +418,13 @@ public:
 
   virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri,
                                       string *out_uri);
+
+  virtual RGWRESTMgr* get_resource_mgr_as_default(struct req_state* s,
+                                                  const std::string& uri,
+                                                  std::string* our_uri) {
+    return this;
+  }
+
   virtual RGWHandler_REST *get_handler(struct req_state *s) { return NULL; }
   virtual void put_handler(RGWHandler_REST *handler) { delete handler; }
 
index dc803265f78bccef902cacf61b6cad73ff7fca18..60a6541f271d603da423e3aa2ba43ee0a7de375c 100644 (file)
@@ -1709,43 +1709,52 @@ int RGWHandler_REST_SWIFT::init_from_header(struct req_state *s)
   s->info.args.set(p);
   s->info.args.parse();
 
-  if (*req_name != '/')
+  /* Skip the leading slash of URL hierarchy. */
+  if (req_name[0] != '/') {
     return 0;
+  } else {
+    req_name++;
+  }
 
-  req_name++;
-
-  if (!*req_name)
-    return 0;
+  if ('\0' == req_name[0]) {
+    return g_conf->rgw_swift_url_prefix == "/" ? -ERR_BAD_URL : 0;
+  }
 
   req = req_name;
 
-  int pos = req.find('/');
-  if (pos >= 0) {
+  size_t pos = req.find('/');
+  if (std::string::npos != pos && g_conf->rgw_swift_url_prefix != "/") {
     bool cut_url = g_conf->rgw_swift_url_prefix.length();
     first = req.substr(0, pos);
+
     if (first.compare(g_conf->rgw_swift_url_prefix) == 0) {
       if (cut_url) {
+        /* Rewind to the "v1/..." part. */
         next_tok(req, first, '/');
       }
     }
+  } else if (req.compare(g_conf->rgw_swift_url_prefix) == 0) {
+    s->formatter = new RGWFormatter_Plain;
+    return -ERR_BAD_URL;
   } else {
-    if (req.compare(g_conf->rgw_swift_url_prefix) == 0) {
-      s->formatter = new RGWFormatter_Plain;
-      return -ERR_BAD_URL;
-    }
     first = req;
   }
 
-  string tenant_path;
-  if (!g_conf->rgw_swift_tenant_name.empty()) {
+  std::string tenant_path;
+  if (! g_conf->rgw_swift_tenant_name.empty()) {
     tenant_path = "/AUTH_";
     tenant_path.append(g_conf->rgw_swift_tenant_name);
   }
 
   /* verify that the request_uri conforms with what's expected */
   char buf[g_conf->rgw_swift_url_prefix.length() + 16 + tenant_path.length()];
-  int blen = sprintf(buf, "/%s/v1%s",
-                   g_conf->rgw_swift_url_prefix.c_str(), tenant_path.c_str());
+  int blen;
+  if (g_conf->rgw_swift_url_prefix == "/") {
+    blen = sprintf(buf, "/v1%s", tenant_path.c_str());
+  } else {
+    blen = sprintf(buf, "/%s/v1%s",
+                   g_conf->rgw_swift_url_prefix.c_str(), tenant_path.c_str());
+  }
   if (s->decoded_uri[0] != '/' ||
     s->decoded_uri.compare(0, blen, buf) !=  0) {
     return -ENOENT;
index 0c4b1e25100cb113955a960bf0a4450a6e38b6f2..249ddfe071f18c224ea2399f8e10e06e8d01bc4f 100644 (file)
@@ -262,6 +262,12 @@ public:
   virtual ~RGWRESTMgr_SWIFT() {}
 
   virtual RGWHandler_REST *get_handler(struct req_state *s);
+
+  RGWRESTMgr* get_resource_mgr_as_default(struct req_state* s,
+                                          const std::string& uri,
+                                          std::string* out_uri) override {
+    return this->get_resource_mgr(s, uri, out_uri);
+  }
 };
 
 #endif