From 87f8389e10ad13329c84a527021315217598b8c6 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 13 Oct 2011 16:02:15 -0700 Subject: [PATCH] rgw: more swift fixes and adjustments --- src/rgw/rgw_common.h | 1 + src/rgw/rgw_op.cc | 2 +- src/rgw/rgw_rest.cc | 52 +++++++++++++++++++++++++++++++++------ src/rgw/rgw_rest_s3.cc | 2 ++ src/rgw/rgw_rest_swift.cc | 6 ++++- 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index cea557a38f24d..8b88fc1a438d1 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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 diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 4f8ebe6bcd4b7..cd4eb9194a26d 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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(); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index ace66096f5ed4..14dd3a9224ff1 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -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()); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index fbd129b10c830..f8c63b95bbd01 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 702659538e7a2..67a2a33275f76 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -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); -- 2.39.5