]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: request state and various op functionality use rgw_obj_key
authorYehuda Sadeh <yehuda@redhat.com>
Fri, 26 Sep 2014 21:18:41 +0000 (14:18 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 16 Jan 2015 22:41:42 +0000 (14:41 -0800)
instead of plain string. This is needed so that we use the object
instance in the processing.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_common.h
src/rgw/rgw_dencoder.cc
src/rgw/rgw_json_enc.cc
src/rgw/rgw_log.cc
src/rgw/rgw_log.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_swift.cc

index 21ba9a850bc5598bc1885ec2b5a5413cd6ca58b6..fb34581d1e3ef3bbb96ffb0978ea996751d24977 100644 (file)
@@ -870,6 +870,76 @@ struct req_info {
   void init_meta_info(bool *found_nad_meta);
 };
 
+struct rgw_obj_key {
+  string name;
+  string instance;
+
+  rgw_obj_key() {}
+  rgw_obj_key(const string& n) {
+    set(n);
+  }
+  rgw_obj_key(const string& n, const string& i) {
+    set(n, i);
+  }
+
+  void set(const cls_rgw_obj_key& k) {
+    name = k.name;
+    instance = k.instance;
+  }
+
+  void transform(cls_rgw_obj_key *k) {
+    k->name = name;
+    k->instance = instance;
+  }
+
+  void set(const string& n) {
+    name = n;
+    instance.clear();
+  }
+
+  void set(const string& n, const string& i) {
+    name = n;
+    instance = i;
+  }
+
+  bool empty() {
+    return name.empty();
+  }
+  bool operator==(const rgw_obj_key& k) const {
+    return (name.compare(k.name) == 0) &&
+           (instance.compare(k.instance) == 0);
+  }
+  bool operator<(const rgw_obj_key& k) const {
+    int r = name.compare(k.name);
+    if (r == 0) {
+      r = instance.compare(k.instance);
+    }
+    return (r < 0);
+  }
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(name, bl);
+    ::encode(instance, bl);
+    ENCODE_FINISH(bl);
+  }
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(name, bl);
+    ::decode(instance, bl);
+    DECODE_FINISH(bl);
+  }
+  void dump(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(rgw_obj_key)
+
+inline ostream& operator<<(ostream& out, const rgw_obj_key &o) {
+  if (o.instance.empty()) {
+    return out << o.name;
+  } else {
+    return out << o.name << "[" << o.instance << "]";
+  }
+}
+
 /** Store all the state necessary to complete and respond to an HTTP request*/
 struct req_state {
    CephContext *cct;
@@ -895,9 +965,9 @@ struct req_state {
 
    rgw_bucket bucket;
    string bucket_name_str;
-   string object_str;
+   rgw_obj_key object;
    string src_bucket_name;
-   string src_object;
+   rgw_obj_key src_object;
    ACLOwner bucket_owner;
    ACLOwner owner;
 
@@ -942,54 +1012,6 @@ struct req_state {
    ~req_state();
 };
 
-struct rgw_obj_key {
-  string name;
-  string instance;
-
-  rgw_obj_key() {}
-  rgw_obj_key(const string& n) {
-    set(n);
-  }
-  rgw_obj_key(const string& n, const string& i) {
-    set(n, i);
-  }
-
-  void set(const cls_rgw_obj_key& k) {
-    name = k.name;
-    instance = k.instance;
-  }
-
-  void transform(cls_rgw_obj_key *k) {
-    k->name = name;
-    k->instance = instance;
-  }
-
-  void set(const string& n) {
-    name = n;
-    instance.clear();
-  }
-
-  void set(const string& n, const string& i) {
-    name = n;
-    instance = i;
-  }
-
-  bool empty() {
-    return name.empty();
-  }
-  bool operator==(const rgw_obj_key& k) const {
-    return (name.compare(k.name) == 0) &&
-           (instance.compare(k.instance) == 0);
-  }
-  bool operator<(const rgw_obj_key& k) const {
-    int r = name.compare(k.name);
-    if (r == 0) {
-      r = instance.compare(k.instance);
-    }
-    return (r < 0);
-  }
-};
-
 /** Store basic data on an object */
 struct RGWObjEnt {
   rgw_obj_key key;
index 9f923bcc4a7859c2a419aa7354e34cb224f8199e..f0f4fce87133a70ff51a3a75fc3eeeb47f81b999 100644 (file)
@@ -200,7 +200,7 @@ void rgw_log_entry::generate_test_instances(list<rgw_log_entry*>& o)
   e->bucket = "bucket";
   e->remote_addr = "1.2.3.4";
   e->user = "user";
-  e->obj = "obj";
+  e->obj = rgw_obj_key("obj");
   e->uri = "http://uri/bucket/obj";
   e->http_status = "200";
   e->error_code = "error_code";
index c4d4437481353955aa07ec960ba5c20074565fad..3585c8ffe373789c4041ef1f83abc4a0ed69f1d4 100644 (file)
@@ -85,7 +85,9 @@ void rgw_log_entry::dump(Formatter *f) const
   f->dump_stream("time") << time;
   f->dump_string("remote_addr", remote_addr);
   f->dump_string("user", user);
-  f->dump_string("obj", obj);
+  stringstream s;
+  s << obj;
+  f->dump_string("obj", s.str());
   f->dump_string("op", op);
   f->dump_string("uri", uri);
   f->dump_string("http_status", http_status);
index 937ee93076b646f95b721426e063140b1e611dba..5c3d924d99228ca5549e9a13e9c825cfca904091 100644 (file)
@@ -293,10 +293,11 @@ int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name, OpsL
     return 0;
   }
 
-  if (!s->object_str.empty())
-    entry.obj = s->object_str.c_str();
-  else
-    entry.obj = "-";
+  if (!s->object.empty()) {
+    entry.obj = s->object;
+  } else {
+    entry.obj = rgw_obj_key("-");
+  }
 
   entry.obj_size = s->obj_size;
 
index 4fd195769885b47a71fbf28363aabf617211d727..9af2bb6ceed71fbd5df03fe48c188821fa1fb57c 100644 (file)
@@ -18,7 +18,7 @@ struct rgw_log_entry {
   utime_t time;
   string remote_addr;
   string user;
-  string obj;
+  rgw_obj_key obj;
   string op;
   string uri;
   string http_status;
@@ -32,14 +32,14 @@ struct rgw_log_entry {
   string bucket_id;
 
   void encode(bufferlist &bl) const {
-    ENCODE_START(6, 5, bl);
+    ENCODE_START(7, 5, bl);
     ::encode(object_owner, bl);
     ::encode(bucket_owner, bl);
     ::encode(bucket, bl);
     ::encode(time, bl);
     ::encode(remote_addr, bl);
     ::encode(user, bl);
-    ::encode(obj, bl);
+    ::encode(obj.name, bl);
     ::encode(op, bl);
     ::encode(uri, bl);
     ::encode(http_status, bl);
@@ -51,10 +51,11 @@ struct rgw_log_entry {
     ::encode(referrer, bl);
     ::encode(bytes_received, bl);
     ::encode(bucket_id, bl);
+    ::encode(obj, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator &p) {
-    DECODE_START_LEGACY_COMPAT_LEN(6, 5, 5, p);
+    DECODE_START_LEGACY_COMPAT_LEN(7, 5, 5, p);
     ::decode(object_owner, p);
     if (struct_v > 3)
       ::decode(bucket_owner, p);
@@ -62,7 +63,7 @@ struct rgw_log_entry {
     ::decode(time, p);
     ::decode(remote_addr, p);
     ::decode(user, p);
-    ::decode(obj, p);
+    ::decode(obj.name, p);
     ::decode(op, p);
     ::decode(uri, p);
     ::decode(http_status, p);
@@ -87,8 +88,12 @@ struct rgw_log_entry {
       } else {
         ::decode(bucket_id, p);
       }
-    } else
+    } else {
       bucket_id = "";
+    }
+    if (struct_v >= 7) {
+      ::decode(obj, p);
+    }
     DECODE_FINISH(p);
   }
   void dump(Formatter *f) const;
index ec9f00406cea90b496107b7d01d1e26c38cc63e4..6cb7e86dfe4fa7fae78b6531feeaf3fe865e058e 100644 (file)
@@ -266,11 +266,10 @@ static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map
 
 static int read_policy(RGWRados *store, struct req_state *s,
                        RGWBucketInfo& bucket_info, map<string, bufferlist>& bucket_attrs,
-                       RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
+                       RGWAccessControlPolicy *policy, rgw_bucket& bucket, rgw_obj_key& object)
 {
   string upload_id;
   upload_id = s->info.args.get("uploadId");
-  string oid = object;
   rgw_obj obj;
 
   if (!s->system_request && bucket_info.flags & BUCKET_SUSPENDED) {
@@ -278,16 +277,17 @@ static int read_policy(RGWRados *store, struct req_state *s,
     return -ERR_USER_SUSPENDED;
   }
 
-  if (!oid.empty() && !upload_id.empty()) {
-    RGWMPObj mp(oid, upload_id);
-    oid = mp.get_meta();
+  if (!object.empty() && !upload_id.empty()) {
+    /* multipart upload */
+    RGWMPObj mp(object.name, upload_id);
+    string oid = mp.get_meta();
     obj.init_ns(bucket, oid, mp_ns);
     obj.set_in_extra_data(true);
   } else {
-    obj.init(bucket, oid);
+    obj = rgw_obj(bucket, object);
   }
   int ret = get_policy_from_attr(s->cct, store, s->obj_ctx, bucket_info, bucket_attrs, policy, obj);
-  if (ret == -ENOENT && object.size()) {
+  if (ret == -ENOENT && !object.empty()) {
     /* object does not exist checking the bucket's ACL to make sure
        that we send a proper error code */
     RGWAccessControlPolicy bucket_policy(s->cct);
@@ -319,7 +319,7 @@ static int read_policy(RGWRados *store, struct req_state *s,
 static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data)
 {
   int ret = 0;
-  string obj_str;
+  rgw_obj_key obj;
   RGWUserInfo bucket_owner_info;
 
   s->bucket_instance_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "bucket-instance");
@@ -362,7 +362,7 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
     s->bucket = s->bucket_info.bucket;
 
     if (s->bucket_exists) {
-      string no_obj;
+      rgw_obj_key no_obj;
       ret = read_policy(store, s, s->bucket_info, s->bucket_attrs, s->bucket_acl, s->bucket, no_obj);
     } else {
       s->bucket_acl->create_default(s->user.user_id, s->user.display_name);
@@ -385,7 +385,7 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
         /*If the operation is delete and if this is the master, don't redirect*/
       } else if (!s->local_source ||
           (s->op != OP_PUT && s->op != OP_COPY) ||
-          s->object_str.empty()) {
+          s->object.empty()) {
         return -ERR_PERMANENT_REDIRECT;
       }
     }
@@ -393,19 +393,18 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
 
   /* we're passed only_bucket = true when we specifically need the bucket's
      acls, that happens on write operations */
-  if (!only_bucket && !s->object_str.empty()) {
+  if (!only_bucket && !s->object.empty()) {
     if (!s->bucket_exists) {
       return -ERR_NO_SUCH_BUCKET;
     }
     s->object_acl = new RGWAccessControlPolicy(s->cct);
 
-    obj_str = s->object_str;
-    rgw_obj obj(s->bucket, obj_str);
+    rgw_obj obj(s->bucket, s->object);
     store->set_atomic(s->obj_ctx, obj);
     if (prefetch_data) {
       store->set_prefetch_data(s->obj_ctx, obj);
     }
-    ret = read_policy(store, s, s->bucket_info, s->bucket_attrs, s->object_acl, s->bucket, obj_str);
+    ret = read_policy(store, s, s->bucket_info, s->bucket_attrs, s->object_acl, s->bucket, s->object);
   }
 
   return ret;
@@ -421,7 +420,7 @@ static void rgw_bucket_object_pre_exec(struct req_state *s)
 
 int RGWGetObj::verify_permission()
 {
-  obj.init(s->bucket, s->object_str);
+  obj = rgw_obj(s->bucket, s->object);
   store->set_atomic(s->obj_ctx, obj);
   store->set_prefetch_data(s->obj_ctx, obj);
 
@@ -462,7 +461,7 @@ int RGWOp::init_quota()
   }
 
   /* only interested in object related ops */
-  if (s->object_str.empty()) {
+  if (s->object.empty()) {
     return 0;
   }
 
@@ -794,7 +793,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
       return r;
     }
     bucket = bucket_info.bucket;
-    string no_obj;
+    rgw_obj_key no_obj;
     bucket_policy = &_bucket_policy;
     r = read_policy(store, s, bucket_info, bucket_attrs, bucket_policy, bucket, no_obj);
     if (r < 0) {
@@ -1455,7 +1454,7 @@ protected:
 public:
   bool immutable_head() { return true; }
   RGWPutObjProcessor_Multipart(const string& bucket_owner, uint64_t _p, req_state *_s) :
-                   RGWPutObjProcessor_Atomic(bucket_owner, _s->bucket, _s->object_str, _p, _s->req_id, false), s(_s) {}
+                   RGWPutObjProcessor_Atomic(bucket_owner, _s->bucket, _s->object.name, _p, _s->req_id, false), s(_s) {}
 };
 
 int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, void *obj_ctx, string *oid_rand)
@@ -1583,7 +1582,7 @@ RGWPutObjProcessor *RGWPutObj::select_processor(bool *is_multipart)
   const string& bucket_owner = s->bucket_owner.get_id();
 
   if (!multipart) {
-    processor = new RGWPutObjProcessor_Atomic(bucket_owner, s->bucket, s->object_str, part_size, s->req_id, s->bucket_info.versioning_enabled);
+    processor = new RGWPutObjProcessor_Atomic(bucket_owner, s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled);
   } else {
     processor = new RGWPutObjProcessor_Multipart(bucket_owner, part_size, s);
   }
@@ -1647,7 +1646,7 @@ void RGWPutObj::execute()
 
   perfcounter->inc(l_rgw_put);
   ret = -EINVAL;
-  if (s->object_str.empty()) {
+  if (s->object.empty()) {
     goto done;
   }
 
@@ -1830,7 +1829,7 @@ RGWPutObjProcessor *RGWPostObj::select_processor()
 
   uint64_t part_size = s->cct->_conf->rgw_obj_stripe_size;
 
-  processor = new RGWPutObjProcessor_Atomic(s->bucket_owner.get_id(), s->bucket, s->object_str, part_size, s->req_id, s->bucket_info.versioning_enabled);
+  processor = new RGWPutObjProcessor_Atomic(s->bucket_owner.get_id(), s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled);
 
   return processor;
 }
@@ -1928,7 +1927,7 @@ done:
 
 int RGWPutMetadata::verify_permission()
 {
-  if (!s->object_str.empty()) {
+  if (!s->object.empty()) {
     if (!verify_object_permission(s, RGW_PERM_WRITE))
       return -EACCES;
   } else {
@@ -1952,7 +1951,7 @@ void RGWPutMetadata::execute()
   map<string, bufferlist>::iterator iter;
   bufferlist bl, cors_bl;
 
-  rgw_obj obj(s->bucket, s->object_str);
+  rgw_obj obj(s->bucket, s->object);
 
   store->set_atomic(s->obj_ctx, obj);
 
@@ -1963,7 +1962,7 @@ void RGWPutMetadata::execute()
   rgw_get_request_metadata(s->cct, s->info, attrs);
 
   /* no need to track object versioning, need it for bucket's data only */
-  RGWObjVersionTracker *ptracker = (!s->object_str.empty() ? NULL : &s->bucket_info.objv_tracker);
+  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
 
   if (s->object) {
     /* check if obj exists, read orig attrs */
@@ -2007,7 +2006,7 @@ void RGWPutMetadata::execute()
     cors_config.encode(cors_bl);
     attrs[RGW_ATTR_CORS] = cors_bl;
   }
-  if (!s->object_str.empty()) {
+  if (!s->object.empty()) {
     ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
   } else {
     ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &rmattrs, ptracker);
@@ -2066,14 +2065,14 @@ void RGWDeleteObj::pre_exec()
 void RGWDeleteObj::execute()
 {
   ret = -EINVAL;
-  rgw_obj obj(s->bucket, s->object_str);
-  if (!s->object_str.empty()) {
+  rgw_obj obj(s->bucket, s->object);
+  if (!s->object.empty()) {
     store->set_atomic(s->obj_ctx, obj);
     ret = store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), obj);
   }
 }
 
-bool RGWCopyObj::parse_copy_location(const char *src, string& bucket_name, string& object)
+bool RGWCopyObj::parse_copy_location(const char *src, string& bucket_name, rgw_obj_key& object)
 {
   string url_src(src);
   string dec_src;
@@ -2090,17 +2089,18 @@ bool RGWCopyObj::parse_copy_location(const char *src, string& bucket_name, strin
     return false;
 
   bucket_name = str.substr(0, pos);
-  object = str.substr(pos + 1);
+  string key = str.substr(pos + 1);
 
-  if (object.size() == 0)
+  if (key.empty())
     return false;
 
+  object = rgw_obj_key(key);
+
   return true;
 }
 
 int RGWCopyObj::verify_permission()
 {
-  string empty_str;
   RGWAccessControlPolicy src_policy(s->cct);
   ret = get_params();
   if (ret < 0)
@@ -2146,8 +2146,10 @@ int RGWCopyObj::verify_permission()
   rgw_obj dest_obj(dest_bucket, dest_object);
   store->set_atomic(s->obj_ctx, dest_obj);
 
+  rgw_obj_key no_obj;
+
   /* check dest bucket permissions */
-  ret = read_policy(store, s, dest_bucket_info, dest_attrs, &dest_bucket_policy, dest_bucket, empty_str);
+  ret = read_policy(store, s, dest_bucket_info, dest_attrs, &dest_bucket_policy, dest_bucket, no_obj);
   if (ret < 0)
     return ret;
 
@@ -2222,13 +2224,11 @@ void RGWCopyObj::pre_exec()
 
 void RGWCopyObj::execute()
 {
-  rgw_obj src_obj, dst_obj;
-
   if (init_common() < 0)
     return;
 
-  src_obj.init(src_bucket, src_object);
-  dst_obj.init(dest_bucket, dest_object);
+  rgw_obj src_obj(src_bucket, src_object);
+  rgw_obj dst_obj(dest_bucket, dest_object);
   store->set_atomic(s->obj_ctx, src_obj);
 
   store->set_atomic(s->obj_ctx, dst_obj);
@@ -2260,7 +2260,7 @@ void RGWCopyObj::execute()
 int RGWGetACLs::verify_permission()
 {
   bool perm;
-  if (!s->object_str.empty()) {
+  if (!s->object.empty()) {
     perm = verify_object_permission(s, RGW_PERM_READ_ACP);
   } else {
     perm = verify_bucket_permission(s, RGW_PERM_READ_ACP);
@@ -2279,7 +2279,7 @@ void RGWGetACLs::pre_exec()
 void RGWGetACLs::execute()
 {
   stringstream ss;
-  RGWAccessControlPolicy *acl = (!s->object_str.empty() ? s->object_acl : s->bucket_acl);
+  RGWAccessControlPolicy *acl = (!s->object.empty() ? s->object_acl : s->bucket_acl);
   RGWAccessControlPolicy_S3 *s3policy = static_cast<RGWAccessControlPolicy_S3 *>(acl);
   s3policy->to_xml(ss);
   acls = ss.str();
@@ -2290,7 +2290,7 @@ void RGWGetACLs::execute()
 int RGWPutACLs::verify_permission()
 {
   bool perm;
-  if (!s->object_str.empty()) {
+  if (!s->object.empty()) {
     perm = verify_object_permission(s, RGW_PERM_WRITE_ACP);
   } else {
     perm = verify_bucket_permission(s, RGW_PERM_WRITE_ACP);
@@ -2376,14 +2376,14 @@ void RGWPutACLs::execute()
     *_dout << dendl;
   }
 
-  RGWObjVersionTracker *ptracker = (!s->object_str.empty() ? NULL : &s->bucket_info.objv_tracker);
+  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
 
   new_policy.encode(bl);
-  obj.init(s->bucket, s->object_str);
+  obj = rgw_obj(s->bucket, s->object);
   map<string, bufferlist> attrs;
   attrs[RGW_ATTR_ACL] = bl;
   store->set_atomic(s->obj_ctx, obj);
-  if (!s->object_str.empty()) {
+  if (!s->object.empty()) {
     ret = store->set_attrs(s->obj_ctx, obj, attrs, NULL, ptracker);
   } else {
     ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, NULL, ptracker);
@@ -2427,7 +2427,7 @@ void RGWPutCORS::execute()
   if (ret < 0)
     return;
 
-  RGWObjVersionTracker *ptracker = (!s->object_str.empty() ? NULL : &s->bucket_info.objv_tracker);
+  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
 
   store->get_bucket_instance_obj(s->bucket, obj);
   store->set_atomic(s->obj_ctx, obj);
@@ -2460,7 +2460,7 @@ void RGWDeleteCORS::execute()
   map<string, bufferlist> orig_attrs, attrs, rmattrs;
   map<string, bufferlist>::iterator iter;
 
-  RGWObjVersionTracker *ptracker = (!s->object_str.empty() ? NULL : &s->bucket_info.objv_tracker);
+  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
 
   /* check if obj exists, read orig attrs */
   ret = get_obj_attrs(store, s, obj, orig_attrs, NULL, ptracker);
@@ -2556,7 +2556,7 @@ void RGWInitMultipart::execute()
   if (get_params() < 0)
     return;
   ret = -EINVAL;
-  if (s->object_str.empty())
+  if (s->object.empty())
     return;
 
   policy.encode(aclbl);
@@ -2578,7 +2578,7 @@ void RGWInitMultipart::execute()
     upload_id.append(buf);
 
     string tmp_obj_name;
-    RGWMPObj mp(s->object_str, upload_id);
+    RGWMPObj mp(s->object.name, upload_id);
     tmp_obj_name = mp.get_meta();
 
     obj.init_ns(s->bucket, tmp_obj_name, mp_ns);
@@ -2775,7 +2775,7 @@ void RGWCompleteMultipart::execute()
     return;
   }
 
-  mp.init(s->object_str, upload_id);
+  mp.init(s->object.name, upload_id);
   meta_oid = mp.get_meta();
 
   int total_parts = 0;
@@ -2872,7 +2872,7 @@ void RGWCompleteMultipart::execute()
 
   attrs[RGW_ATTR_ETAG] = etag_bl;
 
-  target_obj.init(s->bucket, s->object_str);
+  target_obj.init(s->bucket, s->object.name);
 
   store->set_atomic(s->obj_ctx, target_obj);
 
@@ -2920,10 +2920,10 @@ void RGWAbortMultipart::execute()
   RGWMPObj mp;
   const string& owner = s->bucket_owner.get_id();
 
-  if (upload_id.empty() || s->object_str.empty())
+  if (upload_id.empty() || s->object.empty())
     return;
 
-  mp.init(s->object_str, upload_id);
+  mp.init(s->object.name, upload_id);
   meta_oid = mp.get_meta();
 
   ret = get_multipart_info(store, s, meta_oid, NULL, attrs);
@@ -2994,7 +2994,7 @@ void RGWListMultipart::execute()
   if (ret < 0)
     return;
 
-  mp.init(s->object_str, upload_id);
+  mp.init(s->object.name, upload_id);
   meta_oid = mp.get_meta();
 
   ret = get_multipart_info(store, s, meta_oid, &policy, xattrs);
@@ -3159,7 +3159,7 @@ int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket)
   int ret = rgw_build_policies(store, s, only_bucket, op->prefetch_data());
 
   if (ret < 0) {
-    ldout(s->cct, 10) << "read_permissions on " << s->bucket << ":" <<s->object_str << " only_bucket=" << only_bucket << " ret=" << ret << dendl;
+    ldout(s->cct, 10) << "read_permissions on " << s->bucket << ":" <<s->object << " only_bucket=" << only_bucket << " ret=" << ret << dendl;
     if (ret == -ENODATA)
       ret = -EACCES;
   }
index 42e42351d14629d1b4d05004ea1471358e959c0c..776f213fea511d79a4537007cfad9c7ff6bb9c1d 100644 (file)
@@ -572,7 +572,7 @@ protected:
   map<string, bufferlist> attrs;
   string src_bucket_name;
   rgw_bucket src_bucket;
-  string src_object;
+  rgw_obj_key src_object;
   string dest_bucket_name;
   rgw_bucket dest_bucket;
   string dest_object;
@@ -609,7 +609,7 @@ public:
     last_ofs = 0;
   }
 
-  static bool parse_copy_location(const char *src, string& bucket_name, string& object);
+  static bool parse_copy_location(const char *src, string& bucket_name, rgw_obj_key& object);
 
   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
     RGWOp::init(store, s, h);
index ba1b1793b7ea4af67ea95300d4400fa3cba030c2..8d17f057c3eb55014cdb2bedd60542aaf705a64f 100644 (file)
@@ -291,8 +291,8 @@ void dump_uri_from_state(struct req_state *s)
     if (!s->bucket_name_str.empty()) {
       location += s->bucket_name_str;
       location += "/";
-      if (!s->object_str.empty()) {
-        location += s->object_str;
+      if (!s->object.empty()) {
+        location += s->object.name;
         s->cio->print("Location: %s\r\n", location.c_str());
       }
     }
index eceb5d23db01129fbb9f864517bc578830855929..191c5d1a270ca50df943796dcb8c812d70c7dce5 100644 (file)
@@ -1053,19 +1053,22 @@ int RGWPostObj_ObjStore_S3::get_params()
     env.add_var(part.name, part_str);
   } while (!done);
 
-  if (!part_str("key", &s->object_str)) {
+  string object_str;
+  if (!part_str("key", &object_str)) {
     err_msg = "Key not specified";
     return -EINVAL;
   }
 
-  rebuild_key(s->object_str);
+  s->object = rgw_obj_key(object_str);
 
-  if (s->object_str.empty()) {
+  rebuild_key(s->object.name);
+
+  if (s->object.empty()) {
     err_msg = "Empty object name";
     return -EINVAL;
   }
 
-  env.add_var("key", s->object_str);
+  env.add_var("key", s->object.name);
 
   part_str("Content-Type", &content_type);
   env.add_var("Content-Type", content_type);
@@ -1277,7 +1280,7 @@ void RGWPostObj_ObjStore_S3::send_response()
     string etag_url;
 
     url_encode(s->bucket_name_str, bucket);
-    url_encode(s->object_str, key);
+    url_encode(s->object.name, key);
     url_encode(etag_str, etag_url);
 
     redirect.append("?bucket=");
@@ -1324,9 +1327,9 @@ done:
   if (ret == STATUS_CREATED) {
     s->formatter->open_object_section("PostResponse");
     if (g_conf->rgw_dns_name.length())
-      s->formatter->dump_format("Location", "%s/%s", s->info.script_uri.c_str(), s->object_str.c_str());
+      s->formatter->dump_format("Location", "%s/%s", s->info.script_uri.c_str(), s->object.name.c_str());
     s->formatter->dump_string("Bucket", s->bucket_name_str);
-    s->formatter->dump_string("Key", s->object_str);
+    s->formatter->dump_string("Key", s->object.name);
     s->formatter->close_section();
   }
   s->err.message = err_msg;
@@ -1380,7 +1383,7 @@ int RGWCopyObj_ObjStore_S3::get_params()
   src_bucket_name = s->src_bucket_name;
   src_object = s->src_object;
   dest_bucket_name = s->bucket.name;
-  dest_object = s->object_str;
+  dest_object = s->object.name;
 
   if (s->system_request) {
     source_zone = s->info.args.get(RGW_SYS_PARAM_PREFIX "source-zone");
@@ -1411,7 +1414,8 @@ int RGWCopyObj_ObjStore_S3::get_params()
 
   if (source_zone.empty() &&
       (dest_bucket_name.compare(src_bucket_name) == 0) &&
-      (dest_object.compare(src_object) == 0) &&
+      (dest_object.compare(src_object.name) == 0) &&
+      src_object.instance.empty() &&
       !replace_attrs) {
     /* can only copy object into itself if replacing attrs */
     ldout(s->cct, 0) << "can't copy object into itself if not replacing attrs" << dendl;
@@ -1471,7 +1475,7 @@ int RGWPutACLs_ObjStore_S3::get_policy_from_state(RGWRados *store, struct req_st
   RGWAccessControlPolicy_S3 s3policy(s->cct);
 
   // bucket-* canned acls do not apply to bucket
-  if (s->object_str.empty()) {
+  if (s->object.empty()) {
     if (s->canned_acl.find("bucket") != string::npos)
       s->canned_acl.clear();
   }
@@ -1638,7 +1642,7 @@ void RGWInitMultipart_ObjStore_S3::send_response()
     s->formatter->open_object_section_in_ns("InitiateMultipartUploadResult",
                  "http://s3.amazonaws.com/doc/2006-03-01/");
     s->formatter->dump_string("Bucket", s->bucket_name_str);
-    s->formatter->dump_string("Key", s->object_str);
+    s->formatter->dump_string("Key", s->object.name);
     s->formatter->dump_string("UploadId", upload_id);
     s->formatter->close_section();
     rgw_flush_formatter_and_reset(s, s->formatter);
@@ -1658,7 +1662,7 @@ void RGWCompleteMultipart_ObjStore_S3::send_response()
     if (g_conf->rgw_dns_name.length())
       s->formatter->dump_format("Location", "%s.%s", s->bucket_name_str.c_str(), g_conf->rgw_dns_name.c_str());
     s->formatter->dump_string("Bucket", s->bucket_name_str);
-    s->formatter->dump_string("Key", s->object_str);
+    s->formatter->dump_string("Key", s->object.name);
     s->formatter->dump_string("ETag", etag);
     s->formatter->close_section();
     rgw_flush_formatter_and_reset(s, s->formatter);
@@ -1697,7 +1701,7 @@ void RGWListMultipart_ObjStore_S3::send_response()
       cur_max = test_iter->first;
     }
     s->formatter->dump_string("Bucket", s->bucket_name_str);
-    s->formatter->dump_string("Key", s->object_str);
+    s->formatter->dump_string("Key", s->object.name);
     s->formatter->dump_string("UploadId", upload_id);
     s->formatter->dump_string("StorageClass", "STANDARD");
     s->formatter->dump_int("PartNumberMarker", marker);
@@ -2044,10 +2048,10 @@ int RGWHandler_ObjStore_S3::init_from_header(struct req_state *s, int default_fo
 
     if (pos >= 0) {
       string encoded_obj_str = req.substr(pos+1);
-      s->object_str = encoded_obj_str;
+      s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"));
     }
   } else {
-    s->object_str = req_name;
+    s->object = rgw_obj_key(req_name, s->info.args.get("versionId"));
   }
   return 0;
 }
@@ -2112,13 +2116,13 @@ int RGWHandler_ObjStore_S3::validate_bucket_name(const string& bucket, bool rela
 
 int RGWHandler_ObjStore_S3::init(RGWRados *store, struct req_state *s, RGWClientIO *cio)
 {
-  dout(10) << "s->object=" << (!s->object_str.empty() ? s->object_str : "<NULL>") << " s->bucket=" << (!s->bucket_name_str.empty() ? s->bucket_name_str : "<NULL>") << dendl;
+  dout(10) << "s->object=" << (!s->object.empty() ? s->object : rgw_obj_key("<NULL>")) << " s->bucket=" << (!s->bucket_name_str.empty() ? s->bucket_name_str : "<NULL>") << dendl;
 
   bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
   int ret = validate_bucket_name(s->bucket_name_str, relaxed_names);
   if (ret)
     return ret;
-  ret = validate_object_name(s->object_str);
+  ret = validate_object_name(s->object.name);
   if (ret)
     return ret;
 
@@ -2414,7 +2418,7 @@ RGWHandler *RGWRESTMgr_S3::get_handler(struct req_state *s)
   if (s->bucket_name_str.empty())
     return new RGWHandler_ObjStore_Service_S3;
 
-  if (s->object_str.empty())
+  if (s->object.empty())
     return new RGWHandler_ObjStore_Bucket_S3;
 
   return new RGWHandler_ObjStore_Obj_S3;
index e1487329f88c8ab44bfe7b91895f593fc14dee86..48f9462811135af260de5861b05dbd1dbcd90009 100644 (file)
@@ -232,7 +232,7 @@ static void dump_container_metadata(struct req_state *s, RGWBucketEnt& bucket)
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size_rounded);
   s->cio->print("X-Container-Bytes-Used-Actual: %s\r\n", buf);
 
-  if (s->object_str.empty()) {
+  if (s->object.empty()) {
     RGWAccessControlPolicy_SWIFT *swift_policy = static_cast<RGWAccessControlPolicy_SWIFT *>(s->bucket_acl);
     string read_acl, write_acl;
     swift_policy->to_str(read_acl, write_acl);
@@ -400,7 +400,7 @@ int RGWPutObj_ObjStore_SWIFT::get_params()
 
   if (!s->generic_attrs.count(RGW_ATTR_CONTENT_TYPE)) {
     dout(5) << "content type wasn't provided, trying to guess" << dendl;
-    const char *suffix = strrchr(s->object_str.c_str(), '.');
+    const char *suffix = strrchr(s->object.name.c_str(), '.');
     if (suffix) {
       suffix++;
       if (*suffix) {
@@ -436,7 +436,7 @@ int RGWPutMetadata_ObjStore_SWIFT::get_params()
   if (s->has_bad_meta)
     return -EINVAL;
 
-  if (s->object_str.c_str()) {
+  if (s->object.empty()) {
     int r = get_swift_container_settings(s, store, &policy, &has_policy, &cors_config, &has_cors);
     if (r < 0) {
       return r;
@@ -516,7 +516,7 @@ int RGWCopyObj_ObjStore_SWIFT::get_params()
   src_bucket_name = s->src_bucket_name;
   src_object = s->src_object;
   dest_bucket_name = s->bucket_name_str;
-  dest_object = s->object_str;
+  dest_object = s->object.name;
 
   return 0;
 }
@@ -596,7 +596,7 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
       } else {
         if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
           name += sizeof(RGW_ATTR_META_PREFIX) - 1;
-          s->cio->print("X-%s-Meta-%s: %s\r\n", (!s->object_str.empty() ? "Object" : "Container"), name, iter->second.c_str());
+          s->cio->print("X-%s-Meta-%s: %s\r\n", (!s->object.empty() ? "Object" : "Container"), name, iter->second.c_str());
         }
       }
     }
@@ -928,8 +928,8 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
   s->info.effective_uri = "/" + s->bucket_name_str;
 
   if (req.size()) {
-    s->object_str = req;
-    s->info.effective_uri.append("/" + s->object_str);
+    s->object = rgw_obj_key(req, s->info.env->get("HTTP_X_OBJECT_VERSION_ID")); /* rgw swift extension */
+    s->info.effective_uri.append("/" + s->object.name);
   }
 
   return 0;
@@ -937,12 +937,12 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
 
 int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWClientIO *cio)
 {
-  dout(10) << "s->object=" << (!s->object_str.empty() ? s->object_str : "<NULL>") << " s->bucket=" << (!s->bucket_name_str.empty() ? s->bucket_name_str : "<NULL>") << dendl;
+  dout(10) << "s->object=" << (!s->object.empty() ? s->object : rgw_obj_key("<NULL>")) << " s->bucket=" << (!s->bucket_name_str.empty() ? s->bucket_name_str : "<NULL>") << dendl;
 
   int ret = validate_bucket_name(s->bucket_name_str.c_str());
   if (ret)
     return ret;
-  ret = validate_object_name(s->object_str);
+  ret = validate_object_name(s->object.name);
   if (ret)
     return ret;
 
@@ -961,11 +961,12 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
       return -ERR_BAD_URL;
 
     string dest_bucket_name;
-    string dest_object;
-    bool result = RGWCopyObj::parse_copy_location(req_dest, dest_bucket_name, dest_object);
+    rgw_obj_key dest_obj_key;
+    bool result = RGWCopyObj::parse_copy_location(req_dest, dest_bucket_name, dest_obj_key);
     if (!result)
        return -ERR_BAD_URL;
 
+    string dest_object = dest_obj_key.name;
     if (dest_bucket_name != s->bucket_name_str) {
       ret = validate_bucket_name(dest_bucket_name.c_str());
       if (ret < 0)
@@ -974,9 +975,9 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
 
     /* convert COPY operation into PUT */
     s->src_bucket_name = s->bucket_name_str;
-    s->src_object = s->object_str;
+    s->src_object = s->object;
     s->bucket_name_str = dest_bucket_name;
-    s->object_str = dest_object;
+    s->object = rgw_obj_key(dest_object);
     s->op = OP_PUT;
   }
 
@@ -992,7 +993,7 @@ RGWHandler *RGWRESTMgr_SWIFT::get_handler(struct req_state *s)
 
   if (s->bucket_name_str.empty())
     return new RGWHandler_ObjStore_Service_SWIFT;
-  if (s->object_str.empty())
+  if (s->object.empty())
     return new RGWHandler_ObjStore_Bucket_SWIFT;
 
   return new RGWHandler_ObjStore_Obj_SWIFT;
index d2c2898ae5619207350af6b72b28441ca9d50927..8171473546b35853a6cb66cf439f9eefe81071d8 100644 (file)
@@ -536,7 +536,7 @@ int authenticate_temp_url(RGWRados *store, req_state *s)
   if (s->bucket_name_str.empty())
     return -EPERM;
 
-  if (s->object_str.empty())
+  if (s->object.empty())
     return -EPERM;
 
   string temp_url_sig = s->info.args.get("temp_url_sig");