diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-21 14:07:21 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-21 14:07:21 -0700 |
commit | 669e45eaaa8b7364c60666940a4e3f1df56dccf1 (patch) | |
tree | f976bf192cee9c666b21a51de1aa30876d603d60 | |
parent | 7be705e0039b79d6056a99b53a5e098bd95a7c92 (diff) | |
download | ceph-669e45eaaa8b7364c60666940a4e3f1df56dccf1.tar.gz |
rgw: forward bucket creation to master region
plus many fixes.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/rgw/rgw_http_client.cc | 5 | ||||
-rw-r--r-- | src/rgw/rgw_http_client.h | 3 | ||||
-rw-r--r-- | src/rgw/rgw_http_errors.h (renamed from src/rgw/rgw_html_errors.h) | 32 | ||||
-rw-r--r-- | src/rgw/rgw_op.cc | 7 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 5 | ||||
-rw-r--r-- | src/rgw/rgw_rest.cc | 6 | ||||
-rw-r--r-- | src/rgw/rgw_rest_client.cc | 21 | ||||
-rw-r--r-- | src/rgw/rgw_rest_client.h | 8 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 8 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.h | 4 | ||||
-rw-r--r-- | src/rgw/rgw_swift.cc | 4 |
12 files changed, 71 insertions, 34 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ecde5c11320..befa68dda20 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 8472cfc750f..f51b5141afd 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 e11704fdf9e..5e8b55a61b6 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 index 16b06562956..1eb4e12e695 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 d3b3e03c300..7a870236890 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 15408818825..30ce936aa90 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<string, RGWRegion>::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 b7c8e69ea0c..9f093bac1d2 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 0d896652277..d3caaa5c849 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<pair<string, string> >::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<string, string>("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<string, string>("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 f885a223d84..95e1f28697d 100644 --- a/src/rgw/rgw_rest_client.h +++ b/src/rgw/rgw_rest_client.h @@ -15,11 +15,9 @@ protected: map<string, string> out_headers; list<pair<string, string> > params; - - RGWRESTClient() : cct(NULL), status(0) {} public: - RGWRESTClient(CephContext *_cct, string& _url, - list<pair<string, string> > *_headers, list<pair<string, string> > *_params) : cct(_cct), url(_url) { + RGWRESTClient(CephContext *_cct, string& _url, list<pair<string, string> > *_headers, + list<pair<string, string> > *_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 6af11b036c2..a9010d64763 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<string,int>& 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 ea8e5edc2cb..d2f9d7f4baf 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 9b9b1bbefb1..56933b3d722 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; } |