]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: more swift fixes and adjustments
authorYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 13 Oct 2011 23:02:15 +0000 (16:02 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 13 Oct 2011 23:02:15 +0000 (16:02 -0700)
src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc

index cea557a38f24dbfc48cac62e33363d83805a3694..8b88fc1a438d15dbeb01ea75af671a3862b0c590 100644 (file)
@@ -109,6 +109,7 @@ using ceph::crypto::MD5;
 #define ERR_REQUEST_TIMEOUT     2010
 #define ERR_LENGTH_REQUIRED     2011
 #define ERR_REQUEST_TIME_SKEWED 2012
+#define ERR_BUCKET_EXISTS       2013
 #define ERR_USER_SUSPENDED      2100
 #define ERR_INTERNAL_ERROR      2200
 
index 4f8ebe6bcd4b7d944bc8229d5ec45df94bbe1ef7..cd4eb9194a26debdbfccdee46ac76adce3a65c7f 100644 (file)
@@ -521,7 +521,7 @@ void RGWCreateBucket::execute()
     rgw_remove_user_bucket_info(s->user.user_id, s->bucket, false);
 
   if (ret == -EEXIST)
-    ret = 0;
+    ret = -ERR_BUCKET_EXISTS;
 
 done:
   send_response();
index ace66096f5ed47759da28c909e2dc9170d3be7b5..14dd3a9224ff11ef9619e47cfd15ddc98d4b9584 100644 (file)
@@ -29,6 +29,7 @@ struct rgw_html_errors {
 const static struct rgw_html_errors RGW_HTML_ERRORS[] = {
     { 0, 200, "" },
     { 201, 201, "Created" },
+    { 202, 202, "Accepted" },
     { 204, 204, "NoContent" },
     { 206, 206, "" },
     { EINVAL, 400, "InvalidArgument" },
@@ -56,19 +57,44 @@ const static struct rgw_html_errors RGW_HTML_ERRORS[] = {
     { ERR_INTERNAL_ERROR, 500, "InternalError" },
 };
 
+const static struct rgw_html_errors RGW_HTML_SWIFT_ERRORS[] = {
+    { EACCES, 401, "AccessDenied" },
+    { EPERM, 401, "AccessDenied" },
+    { ERR_USER_SUSPENDED, 401, "UserSuspended" },
+};
+
+#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
+
+static const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
+{
+  for (int i = 0; i < len; ++i, ++errs) {
+    if (err_no == errs->err_no)
+      return errs;
+  }
+  return NULL;
+}
+
 void set_req_state_err(struct req_state *s, int err_no)
 {
+  const struct rgw_html_errors *r;
+
   if (err_no < 0)
     err_no = -err_no;
   s->err.ret = err_no;
-  for (size_t i = 0; i < sizeof(RGW_HTML_ERRORS)/sizeof(RGW_HTML_ERRORS[0]); ++i) {
-    const struct rgw_html_errors *r = RGW_HTML_ERRORS + i;
-    if (err_no == r->err_no) {
+  if (s->prot_flags & RGW_REST_SWIFT) {
+    r = search_err(err_no, RGW_HTML_SWIFT_ERRORS, ARRAY_LEN(RGW_HTML_SWIFT_ERRORS));
+    if (r) {
       s->err.http_ret = r->http_ret;
       s->err.s3_code = r->s3_code;
       return;
     }
   }
+  r = search_err(err_no, RGW_HTML_ERRORS, ARRAY_LEN(RGW_HTML_ERRORS));
+  if (r) {
+    s->err.http_ret = r->http_ret;
+    s->err.s3_code = r->s3_code;
+    return;
+  }
   dout(0) << "set_req_state_err err_no=" << err_no << " resorting to 500" << dendl;
 
   s->err.http_ret = 500;
@@ -624,7 +650,7 @@ static bool looks_like_ip_address(const char *bucket)
 
 // This function enforces Amazon's spec for bucket names.
 // (The requirements, not the recommendations.)
-static int validate_bucket_name(const char *bucket)
+static int validate_bucket_name(const char *bucket, int flags)
 {
   int len = strlen(bucket);
   if (len < 3) {
@@ -640,8 +666,12 @@ static int validate_bucket_name(const char *bucket)
     return ERR_INVALID_BUCKET_NAME;
   }
 
-#warning FIXME
-  return 0;
+  if (flags & RGW_REST_SWIFT) {
+    if (*bucket == '.')
+      return ERR_INVALID_BUCKET_NAME;
+
+    return 0;
+  }
 
   if (!(isalpha(bucket[0]) || isdigit(bucket[0]))) {
     // bucket names must start with a number or letter
@@ -735,10 +765,18 @@ int RGWHandler_REST::preprocess(struct req_state *s, FCGX_Request *fcgx)
     break;
   }
 
+  if (s->prot_flags & RGW_REST_SWIFT) {
+    char buf[g_conf->rgw_swift_url_prefix.length() + 16];
+    int blen = sprintf(buf, "/%s/v1", g_conf->rgw_swift_url_prefix.c_str());
+    if (s->path_name_url[0] != '/' ||
+        s->path_name_url.compare(0, blen, buf) !=  0)
+      ret = -ENOENT;
+  }
+
   if (ret)
     return ret;
 
-  ret = validate_bucket_name(s->bucket_name_str.c_str());
+  ret = validate_bucket_name(s->bucket_name_str.c_str(), s->prot_flags);
   if (ret)
     return ret;
   ret = validate_object_name(s->object_str.c_str());
index fbd129b10c830d9f2510b7537eabef81f9654c48..f8c63b95bbd0130462d55ff5f486eaa9e35bf492 100644 (file)
@@ -165,6 +165,8 @@ void RGWListBucket_REST_S3::send_response()
 
 void RGWCreateBucket_REST_S3::send_response()
 {
+  if (ret == -ERR_BUCKET_EXISTS)
+    ret = 0;
   if (ret)
     set_req_state_err(s, ret);
   dump_errno(s);
index 702659538e7a230342029962fec40247f0cf8cac..67a2a33275f76b2c70dcc084138a032defaf8b72 100644 (file)
@@ -101,8 +101,10 @@ void RGWListBucket_REST_SWIFT::send_response()
 
   if (!ret && s->formatter->get_len() == 0)
     ret = 204;
+  else if (ret > 0)
+    ret = 0;
 
-  set_req_state_err(s, (ret < 0 ? ret : 0));
+  set_req_state_err(s, ret);
   dump_errno(s);
 
   dump_start(s);
@@ -167,6 +169,8 @@ void RGWCreateBucket_REST_SWIFT::send_response()
 {
   if (!ret)
     ret = 201; // "created"
+  else if (ret == -ERR_BUCKET_EXISTS)
+    ret = 202;
   set_req_state_err(s, ret);
   dump_errno(s);
   end_header(s);