From 669e45eaaa8b7364c60666940a4e3f1df56dccf1 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 21 May 2013 14:07:21 -0700 Subject: [PATCH] rgw: forward bucket creation to master region plus many fixes. Signed-off-by: Yehuda Sadeh --- src/Makefile.am | 2 +- src/rgw/rgw_http_client.cc | 5 +-- src/rgw/rgw_http_client.h | 3 +- .../{rgw_html_errors.h => rgw_http_errors.h} | 32 +++++++++++++++---- src/rgw/rgw_op.cc | 7 +++- src/rgw/rgw_rados.cc | 5 +++ src/rgw/rgw_rest.cc | 6 ++-- src/rgw/rgw_rest_client.cc | 21 ++++++++---- src/rgw/rgw_rest_client.h | 8 ++--- src/rgw/rgw_rest_s3.cc | 8 ++--- src/rgw/rgw_rest_s3.h | 4 +-- src/rgw/rgw_swift.cc | 4 +-- 12 files changed, 71 insertions(+), 34 deletions(-) rename src/rgw/{rgw_html_errors.h => rgw_http_errors.h} (77%) diff --git a/src/Makefile.am b/src/Makefile.am index ecde5c1132090..befa68dda207c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2059,7 +2059,7 @@ noinst_HEADERS = \ rgw/rgw_cors_swift.h\ rgw/rgw_string.h\ rgw/rgw_formats.h\ - rgw/rgw_html_errors.h\ + rgw/rgw_http_errors.h\ rgw/rgw_log.h\ rgw/rgw_multi.h\ rgw/rgw_policy_s3.h\ diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 8472cfc750f92..f51b5141afdfc 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -30,7 +30,7 @@ static size_t read_http_data(void *ptr, size_t size, size_t nmemb, void *_info) return len; } -int RGWHTTPClient::process(const string& url) +int RGWHTTPClient::process(const char *method, const char *url) { int ret = 0; CURL *curl_handle; @@ -52,7 +52,8 @@ int RGWHTTPClient::process(const string& url) h = curl_slist_append(h, val.c_str()); } - curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, method); + curl_easy_setopt(curl_handle, CURLOPT_URL, url); curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, read_http_header); diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h index e11704fdf9e67..5e8b55a61b638 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -18,7 +18,8 @@ public: virtual int read_header(void *ptr, size_t len) { return 0; } virtual int read_data(void *ptr, size_t len) { return 0; } - int process(const string& url); + int process(const char *method, const char *url); + int process(const char *url) { return process("GET", url); } }; #endif diff --git a/src/rgw/rgw_html_errors.h b/src/rgw/rgw_http_errors.h similarity index 77% rename from src/rgw/rgw_html_errors.h rename to src/rgw/rgw_http_errors.h index 16b0656295655..1eb4e12e695cf 100644 --- a/src/rgw/rgw_html_errors.h +++ b/src/rgw/rgw_http_errors.h @@ -1,15 +1,15 @@ -#ifndef RGW_HTML_ERRORS_H_ -#define RGW_HTML_ERRORS_H_ +#ifndef RGW_HTTP_ERRORS_H_ +#define RGW_HTTP_ERRORS_H_ #include "rgw_common.h" -struct rgw_html_errors { +struct rgw_http_errors { int err_no; int http_ret; const char *s3_code; }; -const static struct rgw_html_errors RGW_HTML_ERRORS[] = { +const static struct rgw_http_errors RGW_HTTP_ERRORS[] = { { 0, 200, "" }, { STATUS_CREATED, 201, "Created" }, { STATUS_ACCEPTED, 202, "Accepted" }, @@ -50,7 +50,7 @@ const static struct rgw_html_errors RGW_HTML_ERRORS[] = { { ERR_INTERNAL_ERROR, 500, "InternalError" }, }; -const static struct rgw_html_errors RGW_HTML_SWIFT_ERRORS[] = { +const static struct rgw_http_errors RGW_HTTP_SWIFT_ERRORS[] = { { EACCES, 401, "AccessDenied" }, { EPERM, 401, "AccessDenied" }, { ERR_USER_SUSPENDED, 401, "UserSuspended" }, @@ -60,7 +60,7 @@ const static struct rgw_html_errors RGW_HTML_SWIFT_ERRORS[] = { #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) -static inline const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len) +static inline const struct rgw_http_errors *search_err(int err_no, const struct rgw_http_errors *errs, int len) { for (int i = 0; i < len; ++i, ++errs) { if (err_no == errs->err_no) @@ -70,5 +70,25 @@ static inline const struct rgw_html_errors *search_err(int err_no, const struct } +static inline int rgw_http_error_to_errno(int http_err) +{ + if (http_err >= 200 && http_err <= 299) + return 0; + switch (http_err) { + case 400: + return -EINVAL; + case 401: + return -EPERM; + case 403: + return -EACCES; + case 404: + return -ENOENT; + default: + return -EIO; + } + + return 0; /* unreachable */ +} + #endif diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index d3b3e03c300d8..7a870236890c4 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -860,10 +860,15 @@ void RGWCreateBucket::execute() if (!store->region.is_master) { if (store->region.api_name != location_constraint) { - ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << dendl; + ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << " (" << store->region.api_name << ")" << dendl; ret = -EINVAL; return; } + + ldout(s->cct, 0) << "sending create_bucket request to master region" << dendl; + ret = store->rest_conn->create_bucket(s->user.user_id, s->bucket_name_str); + if (ret < 0) + return; } s->bucket_owner.set_id(s->user.user_id); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 154088188257a..30ce936aa904b 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -504,6 +504,7 @@ void RGWRados::finalize() delete gc; gc = NULL; } + delete rest_conn; } /** @@ -553,6 +554,10 @@ int RGWRados::init_complete() ldout(cct, 0) << "WARNING: cannot read region map" << dendl; } else { string master_region = region_map.master_region; + if (master_region.empty()) { + lderr(cct) << "ERROR: region map does not specify master region" << dendl; + return -EINVAL; + } map::iterator iter = region_map.regions.find(master_region); if (iter == region_map.regions.end()) { lderr(cct) << "ERROR: bad region map: inconsistent master region" << dendl; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index b7c8e69ea0cae..9f093bac1d223 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -189,20 +189,20 @@ void rgw_flush_formatter(struct req_state *s, Formatter *formatter) void set_req_state_err(struct req_state *s, int err_no) { - const struct rgw_html_errors *r; + const struct rgw_http_errors *r; if (err_no < 0) err_no = -err_no; s->err.ret = err_no; if (s->prot_flags & RGW_REST_SWIFT) { - r = search_err(err_no, RGW_HTML_SWIFT_ERRORS, ARRAY_LEN(RGW_HTML_SWIFT_ERRORS)); + r = search_err(err_no, RGW_HTTP_SWIFT_ERRORS, ARRAY_LEN(RGW_HTTP_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)); + r = search_err(err_no, RGW_HTTP_ERRORS, ARRAY_LEN(RGW_HTTP_ERRORS)); if (r) { s->err.http_ret = r->http_ret; s->err.s3_code = r->s3_code; diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index 0d89665227791..d3caaa5c84964 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -1,5 +1,6 @@ #include "rgw_common.h" #include "rgw_rest_client.h" +#include "rgw_http_errors.h" #include "common/ceph_crypto_cms.h" #include "common/armor.h" @@ -21,15 +22,15 @@ int RGWRESTClient::read_header(void *ptr, size_t len) } if (*s == '\n') { *p = '\0'; - ldout(cct, 10) << "os_auth:" << line << dendl; + ldout(cct, 10) << "received header:" << line << dendl; // TODO: fill whatever data required here char *l = line; char *tok = strsep(&l, " \t:"); - if (tok) { - while (l && *l == ' ') + if (tok && l) { + while (*l == ' ') l++; - if (strcmp(tok, "HTTP") == 0) { + if (strcmp(tok, "HTTP") == 0 || strncmp(tok, "HTTP/", 5) == 0) { status = atoi(l); } else { /* convert header field name to upper case */ @@ -50,7 +51,7 @@ int RGWRESTClient::read_header(void *ptr, size_t len) return 0; } -int RGWRESTClient::execute(RGWAccessKey& key, const string& method, const string& resource) +int RGWRESTClient::execute(RGWAccessKey& key, const char *method, const char *resource) { string new_url = url; string new_resource = resource; @@ -68,6 +69,8 @@ int RGWRESTClient::execute(RGWAccessKey& key, const string& method, const string list >::iterator iter; for (iter = params.begin(); iter != params.end(); ++iter) { + if (iter != params.begin()) + new_url.append("?"); new_url.append(iter->first + "=" + iter->second); } } @@ -78,7 +81,7 @@ int RGWRESTClient::execute(RGWAccessKey& key, const string& method, const string string date_str = s.str(); headers.push_back(make_pair("HTTP_DATE", date_str)); - string canonical_header = method + " " + + string canonical_header = string(method) + " " + "\n" + /* CONTENT_MD5 */ "\n" + /* CONTENT_TYPE */ date_str + "\n" + @@ -103,7 +106,11 @@ int RGWRESTClient::execute(RGWAccessKey& key, const string& method, const string string auth_hdr = "AWS " + key.id + ":" + b64; headers.push_back(make_pair("AUTHORIZATION", auth_hdr)); - return process(new_url); + int r = process(method, new_url.c_str()); + if (r < 0) + return r; + + return rgw_http_error_to_errno(status); } diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h index f885a223d8482..95e1f28697df5 100644 --- a/src/rgw/rgw_rest_client.h +++ b/src/rgw/rgw_rest_client.h @@ -15,11 +15,9 @@ protected: map out_headers; list > params; - - RGWRESTClient() : cct(NULL), status(0) {} public: - RGWRESTClient(CephContext *_cct, string& _url, - list > *_headers, list > *_params) : cct(_cct), url(_url) { + RGWRESTClient(CephContext *_cct, string& _url, list > *_headers, + list > *_params) : cct(_cct), status(0), url(_url) { if (_headers) headers = *_headers; @@ -29,7 +27,7 @@ public: int read_header(void *ptr, size_t len); - int execute(RGWAccessKey& key, const string& method, const string& resource); + int execute(RGWAccessKey& key, const char *method, const char *resource); }; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 6af11b036c27a..a9010d647637a 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -39,10 +39,10 @@ void dump_bucket(struct req_state *s, RGWBucketEnt& obj) s->formatter->close_section(); } -void rgw_get_errno_s3(rgw_html_errors *e , int err_no) +void rgw_get_errno_s3(rgw_http_errors *e , int err_no) { - const struct rgw_html_errors *r; - r = search_err(err_no, RGW_HTML_ERRORS, ARRAY_LEN(RGW_HTML_ERRORS)); + const struct rgw_http_errors *r; + r = search_err(err_no, RGW_HTTP_ERRORS, ARRAY_LEN(RGW_HTTP_ERRORS)); if (r) { e->http_ret = r->http_ret; @@ -1593,7 +1593,7 @@ void RGWDeleteMultiObj_ObjStore_S3::send_partial_response(pair& resu s->formatter->dump_string("Key", result.first); s->formatter->close_section(); } else if (result.first < 0) { - struct rgw_html_errors r; + struct rgw_http_errors r; int err_no; s->formatter->open_object_section("Error"); diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index ea8e5edc2cbb0..d2f9d7f4baf70 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -3,13 +3,13 @@ #define TIME_BUF_SIZE 128 #include "rgw_op.h" -#include "rgw_html_errors.h" +#include "rgw_http_errors.h" #include "rgw_acl_s3.h" #include "rgw_policy_s3.h" #define RGW_AUTH_GRACE_MINS 15 -void rgw_get_errno_s3(struct rgw_html_errors *e, int err_no); +void rgw_get_errno_s3(struct rgw_http_errors *e, int err_no); class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore { diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc index 9b9b1bbefb1d2..56933b3d72222 100644 --- a/src/rgw/rgw_swift.cc +++ b/src/rgw/rgw_swift.cc @@ -396,7 +396,7 @@ int RGWSwift::check_revoked() req.append_header("X-Auth-Token", g_conf->rgw_keystone_admin_token); - int ret = req.process(url); + int ret = req.process(url.c_str()); if (ret < 0) return ret; @@ -604,7 +604,7 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru validate.append_header("X-Auth-Token", g_conf->rgw_keystone_admin_token); - int ret = validate.process(url); + int ret = validate.process(url.c_str()); if (ret < 0) return ret; } -- 2.39.5