]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: virtual hosted-style support
authorlvshanchun <lvshanchun@gmail.com>
Wed, 29 Nov 2017 08:28:05 +0000 (16:28 +0800)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 12 Apr 2018 22:38:37 +0000 (15:38 -0700)
add host-style field in tier-config to specify the related
zone's hosted-style used in request from RGW, if this config
is not specified, path hosted-style will be used as default.

Signed-off-by: lvshanchun <lvshanchun@gmail.com>
src/rgw/rgw_common.h
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_client.h
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_sync_module_aws.cc

index e6f59a86f437fed41d7111afccfc51e71b70ee0e..5b19d16130ee16d3488d0a29a7cea54548b2a977 100644 (file)
@@ -283,6 +283,11 @@ enum RGWObjCategory {
   RGW_OBJ_CATEGORY_MULTIMETA = 3,
 };
 
+enum HostStyle {
+  PathStyle = 0,
+  VirtualStyle = 1,
+};
+
 /** Store error returns for output at a different point in the program */
 struct rgw_err {
   rgw_err();
index 995d211fb219adb38fa26686c3433ca4fd958a59..01d6674e1ca1eefb15b9b822227ce5229cbcdb30 100644 (file)
@@ -438,9 +438,24 @@ static void add_grants_headers(map<int, string>& grants, RGWEnv& env, map<string
 
 void RGWRESTStreamS3PutObj::send_init(rgw_obj& obj)
 {
+  string resource_str;
   string resource;
-  url_encode(obj.bucket.name + "/" + obj.get_oid(), resource);
   string new_url = url;
+
+  if (host_style == VirtualStyle) {
+    resource_str = obj.get_oid();
+    new_url = obj.bucket.name + "."  + new_url;
+  } else {
+    resource_str = obj.bucket.name + "/" + obj.get_oid();
+  }
+
+  //do not encode slash in object key name
+  url_encode(resource_str, resource, false);
+
+  string uri;
+  //do not encode slash in object key name
+  url_encode(obj.bucket.name + "/" + obj.get_oid(), uri, false);
+
   if (new_url[new_url.size() - 1] != '/')
     new_url.append("/");
 
@@ -463,7 +478,7 @@ void RGWRESTStreamS3PutObj::send_init(rgw_obj& obj)
   new_info.method = "PUT";
 
   new_info.script_uri = "/";
-  new_info.script_uri.append(resource);
+  new_info.script_uri.append(uri);
   new_info.request_uri = new_info.script_uri;
 
   method = new_info.method;
@@ -610,7 +625,7 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
   string new_url = url;
   if (new_url[new_url.size() - 1] != '/')
     new_url.append("/");
-
+  
   string date_str;
   get_gmt_date_str(date_str);
 
@@ -627,12 +642,34 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
   }
 
   string new_resource;
+  string bucket_name;
+  string old_resource = resource;
+
   if (resource[0] == '/') {
     new_resource = resource.substr(1);
   } else {
     new_resource = resource;
   }
 
+  string uri = new_resource;
+
+  size_t pos = new_resource.find("/");
+  bucket_name = new_resource.substr(0, pos);
+
+  //when dest is a bucket with out other params, uri should end up with '/'
+  if(pos == string::npos && params.size() == 0 && host_style == VirtualStyle) {
+    uri.append("/");
+  }
+
+  if (host_style == VirtualStyle) {
+    new_url = bucket_name + "." + new_url;
+    if(pos == string::npos) {
+      new_resource = "";
+    } else {
+      new_resource = new_resource.substr(pos+1);
+    }
+  }
+
   new_url.append(new_resource + params_str);
 
   new_env.set("HTTP_DATE", date_str.c_str());
@@ -645,7 +682,7 @@ int RGWRESTStreamRWRequest::do_send_prepare(RGWAccessKey *key, map<string, strin
   new_info.method = method.c_str();
 
   new_info.script_uri = "/";
-  new_info.script_uri.append(new_resource);
+  new_info.script_uri.append(uri);
   new_info.request_uri = new_info.script_uri;
 
   new_info.init_meta_info(NULL);
index 28bf0d772fe9102bf24305da81a9a0f43b11e56e..728460e62e95759783717724a7e4301f9d9f83aa 100644 (file)
@@ -144,9 +144,11 @@ public:
 
 class RGWRESTStreamRWRequest : public RGWHTTPStreamRWRequest {
   bool send_data_hint{false};
+protected:
+  HostStyle host_style;
 public:
   RGWRESTStreamRWRequest(CephContext *_cct, const string& _method, const string& _url, RGWHTTPStreamRWRequest::ReceiveCB *_cb,
-               param_vec_t *_headers, param_vec_t *_params) : RGWHTTPStreamRWRequest(_cct, _method, _url, _cb, _headers, _params) {
+               param_vec_t *_headers, param_vec_t *_params, HostStyle _host_style = PathStyle) : RGWHTTPStreamRWRequest(_cct, _method, _url, _cb, _headers, _params), host_style(_host_style) {
   }
   virtual ~RGWRESTStreamRWRequest() override {}
 
@@ -168,7 +170,7 @@ private:
 class RGWRESTStreamReadRequest : public RGWRESTStreamRWRequest {
 public:
   RGWRESTStreamReadRequest(CephContext *_cct, const string& _url, ReceiveCB *_cb, param_vec_t *_headers,
-               param_vec_t *_params) : RGWRESTStreamRWRequest(_cct, "GET", _url, _cb, _headers, _params) {}
+               param_vec_t *_params, HostStyle _host_style = PathStyle) : RGWRESTStreamRWRequest(_cct, "GET", _url, _cb, _headers, _params, _host_style) {}
 };
 
 class RGWRESTStreamHeadRequest : public RGWRESTStreamRWRequest {
@@ -183,7 +185,7 @@ class RGWRESTStreamS3PutObj : public RGWRESTStreamRWRequest {
   req_info new_info;
 public:
   RGWRESTStreamS3PutObj(CephContext *_cct, const string& _method, const string& _url, param_vec_t *_headers,
-               param_vec_t *_params) : RGWRESTStreamRWRequest(_cct, _method, _url, nullptr, _headers, _params),
+               param_vec_t *_params, HostStyle _host_style) : RGWRESTStreamRWRequest(_cct, _method, _url, nullptr, _headers, _params, _host_style),
                 out_cb(NULL), new_info(cct, &new_env) {}
   ~RGWRESTStreamS3PutObj() override;
 
index 531da9e6d33d821927d3523c14162b2a8d10975a..dbca6d6713013e0c8dc69f0aba94d65e371cf535 100644 (file)
@@ -8,10 +8,11 @@
 
 RGWRESTConn::RGWRESTConn(CephContext *_cct, RGWRados *store,
                          const string& _remote_id,
-                         const list<string>& remote_endpoints)
+                         const list<string>& remote_endpoints,
+                         HostStyle _host_style)
   : cct(_cct),
     endpoints(remote_endpoints.begin(), remote_endpoints.end()),
-    remote_id(_remote_id)
+    remote_id(_remote_id), host_style(_host_style)
 {
   if (store) {
     key = store->get_zone_params().system_key;
@@ -22,11 +23,12 @@ RGWRESTConn::RGWRESTConn(CephContext *_cct, RGWRados *store,
 RGWRESTConn::RGWRESTConn(CephContext *_cct, RGWRados *store,
                          const string& _remote_id,
                          const list<string>& remote_endpoints,
-                         RGWAccessKey _cred)
+                         RGWAccessKey _cred,
+                         HostStyle _host_style)
   : cct(_cct),
     endpoints(remote_endpoints.begin(), remote_endpoints.end()),
     key(std::move(_cred)),
-    remote_id(_remote_id)
+    remote_id(_remote_id), host_style(_host_style)
 {
   if (store) {
     self_zone_group = store->get_zonegroup().get_id();
@@ -126,7 +128,7 @@ int RGWRESTConn::put_obj_send_init(rgw_obj& obj, const rgw_http_param_pair *extr
     append_param_list(params, extra_params);
   }
 
-  RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, &params);
+  RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, &params, host_style);
   wr->send_init(obj);
   *req = wr;
   return 0;
@@ -143,7 +145,7 @@ int RGWRESTConn::put_obj_async(const rgw_user& uid, rgw_obj& obj, uint64_t obj_s
 
   param_vec_t params;
   populate_params(params, &uid, self_zone_group);
-  RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, &params);
+  RGWRESTStreamS3PutObj *wr = new RGWRESTStreamS3PutObj(cct, "PUT", url, NULL, &params, host_style);
   ret = wr->put_obj_init(key, obj, obj_size, attrs, send);
   if (ret < 0) {
     delete wr;
@@ -233,7 +235,7 @@ int RGWRESTConn::get_obj(const rgw_obj& obj, const get_obj_params& in_params, bo
     params.push_back(param_pair_t("versionId", instance));
   }
   if (in_params.get_op) {
-    *req = new RGWRESTStreamReadRequest(cct, url, in_params.cb, NULL, &params);
+    *req = new RGWRESTStreamReadRequest(cct, url, in_params.cb, NULL, &params, host_style);
   } else {
     *req = new RGWRESTStreamHeadRequest(cct, url, in_params.cb, NULL, &params);
   }
@@ -321,7 +323,7 @@ int RGWRESTConn::get_resource(const string& resource,
 
   RGWStreamIntoBufferlist cb(bl);
 
-  RGWRESTStreamReadRequest req(cct, url, &cb, NULL, &params);
+  RGWRESTStreamReadRequest req(cct, url, &cb, NULL, &params, host_style);
 
   map<string, string> headers;
   if (extra_headers) {
@@ -405,7 +407,7 @@ RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn *_conn,
                                          RGWHTTPManager *_mgr)
   : cct(_conn->get_ctx()), conn(_conn), method(_method), resource(_resource),
     params(make_param_list(pp)), cb(bl), mgr(_mgr),
-    req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL)
+    req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL, _conn->get_host_style())
 {
   init_common(extra_headers);
 }
@@ -417,7 +419,7 @@ RGWRESTSendResource::RGWRESTSendResource(RGWRESTConn *_conn,
                                         param_vec_t *extra_headers,
                                          RGWHTTPManager *_mgr)
   : cct(_conn->get_ctx()), conn(_conn), method(_method), resource(_resource), params(params),
-    cb(bl), mgr(_mgr), req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL)
+    cb(bl), mgr(_mgr), req(cct, method.c_str(), conn->get_url(), &cb, NULL, NULL, _conn->get_host_style())
 {
   init_common(extra_headers);
 }
index 1385e870633a9bc278e349d279429a0fdd83ee8a..76a462fa09e1ba753034b8aab230fb8df5ffa2ec 100644 (file)
@@ -62,12 +62,14 @@ class RGWRESTConn
   RGWAccessKey key;
   string self_zone_group;
   string remote_id;
+  HostStyle host_style;
   std::atomic<int64_t> counter = { 0 };
 
 public:
 
-  RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints);
-  RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, RGWAccessKey _cred);
+  RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, HostStyle _host_style = PathStyle);
+  RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, RGWAccessKey _cred, HostStyle _host_style = PathStyle);
+
   // custom move needed for atomic
   RGWRESTConn(RGWRESTConn&& other);
   RGWRESTConn& operator=(RGWRESTConn&& other);
@@ -85,6 +87,10 @@ public:
     return key;
   }
 
+  HostStyle get_host_style() {
+    return host_style;
+  }
+
   CephContext *get_ctx() {
     return cct;
   }
@@ -170,11 +176,11 @@ class S3RESTConn : public RGWRESTConn {
 
 public:
 
-  S3RESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints) :
-    RGWRESTConn(_cct, store, _remote_id, endpoints) {}
+  S3RESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, HostStyle _host_style = PathStyle) :
+    RGWRESTConn(_cct, store, _remote_id, endpoints, _host_style) {}
 
-  S3RESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, RGWAccessKey _cred):
-    RGWRESTConn(_cct, store, _remote_id, endpoints, _cred) {}
+  S3RESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints, RGWAccessKey _cred, HostStyle _host_style = PathStyle):
+    RGWRESTConn(_cct, store, _remote_id, endpoints, _cred, _host_style) {}
   ~S3RESTConn() override = default;
 
   void populate_params(param_vec_t& params, const rgw_user *uid, const string& zonegroup) override {
index 30d3aa74d9526c98c089af95b7313025b8434d85..a526374582c7044ac3e5ea0340556ba2bf89fce7 100644 (file)
@@ -29,7 +29,6 @@ static string aws_bucket_name(const RGWBucketInfo& bucket_info, bool user_bucket
 }
 
 static string aws_object_name(const RGWBucketInfo& bucket_info, const rgw_obj_key&key, bool user_buckets=false){
-  string bucket_name = aws_bucket_name(bucket_info, user_buckets);
   string object_name;
   object_name += bucket_info.owner.to_str() + "/";
   object_name += bucket_info.bucket.name + "/" + key.name;
@@ -44,6 +43,8 @@ static string obj_to_aws_path(const rgw_obj& obj)
 struct AWSSyncConfig {
   string s3_endpoint;
   RGWAccessKey key;
+  HostStyle host_style;
+
 
   uint64_t multipart_sync_threshold{DEFAULT_MULTIPART_SYNC_PART_SIZE};
   uint64_t multipart_min_part_size{DEFAULT_MULTIPART_SYNC_PART_SIZE};
@@ -757,7 +758,6 @@ class RGWAWSHandleRemoteObjCBCR: public RGWStatRemoteObjCBCR {
   unordered_map <string, bool> bucket_created;
   string target_bucket_name;
   rgw_rest_obj rest_obj;
-  string obj_path;
   int ret{0};
 
   uint32_t src_zone_short_id{0};
@@ -799,8 +799,6 @@ public:
         return set_cr_error(-EINVAL);
       }
 
-      obj_path = bucket_info.bucket.name + "/" + key.name;
-
       target_bucket_name = aws_bucket_name(bucket_info);
       if (bucket_created.find(target_bucket_name) == bucket_created.end()){
         yield {
@@ -918,7 +916,8 @@ public:
                                     sync_env->store,
                                     instance.id,
                                     { instance.conf.s3_endpoint },
-                                    instance.conf.key));
+                                    instance.conf.key,
+                                    instance.conf.host_style));
   }
 
   ~RGWAWSDataSyncModule() {}
@@ -971,6 +970,17 @@ int RGWAWSSyncModule::create_instance(CephContext *cct, const JSONFormattable& c
 
   conf.s3_endpoint = config["s3_endpoint"];
 
+  i = config.find("host_style");
+  string host_style_str = config["host_style"];
+
+  if (host_style_str != "virtual") {
+    conf.host_style = PathStyle;
+  } else {
+    conf.host_style = VirtualStyle;
+  }
+
+  conf.bucket_suffix = config["bucket_suffix"];
+
   string access_key = config["access_key"];
   string secret = config["secret"];