diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-23 23:14:35 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-23 23:14:35 -0700 |
commit | 580a08c6d658dfbcba13d8e92ebbfca8297a2dee (patch) | |
tree | 3e97d9d477eeea81d33bdf00568d4a12fef5be4d | |
parent | 2655c1e459197e9c4d863f29ee05a95f9f1f1129 (diff) | |
download | ceph-580a08c6d658dfbcba13d8e92ebbfca8297a2dee.tar.gz |
rgw: multiple fixes and cleanups
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/rgw_auth_s3.cc | 22 | ||||
-rw-r--r-- | src/rgw/rgw_auth_s3.h | 2 | ||||
-rw-r--r-- | src/rgw/rgw_common.cc | 11 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_http_client.cc | 4 | ||||
-rw-r--r-- | src/rgw/rgw_op.cc | 2 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_rest_client.cc | 36 | ||||
-rw-r--r-- | src/rgw/rgw_rest_conn.cc | 17 | ||||
-rw-r--r-- | src/rgw/rgw_rest_conn.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 2 |
11 files changed, 75 insertions, 24 deletions
diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index 89cc80d3421..5a88d3b5e1a 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -142,7 +142,7 @@ static inline bool is_base64_for_content_md5(unsigned char c) { * get the header authentication information required to * compute a request's signature */ -bool rgw_create_s3_canonical_header(req_info& info, utime_t& header_time, string& dest, bool qsr) +bool rgw_create_s3_canonical_header(req_info& info, utime_t *header_time, string& dest, bool qsr) { const char *content_md5 = info.env->get("HTTP_CONTENT_MD5"); if (content_md5) { @@ -172,16 +172,18 @@ bool rgw_create_s3_canonical_header(req_info& info, utime_t& header_time, string } } - struct tm t; - if (!parse_rfc2616(req_date, &t)) { - dout(0) << "NOTICE: failed to parse date for auth header" << dendl; - return false; - } - if (t.tm_year < 70) { - dout(0) << "NOTICE: bad date (predates epoch): " << req_date << dendl; - return false; + if (header_time) { + struct tm t; + if (!parse_rfc2616(req_date, &t)) { + dout(0) << "NOTICE: failed to parse date for auth header" << dendl; + return false; + } + if (t.tm_year < 70) { + dout(0) << "NOTICE: bad date (predates epoch): " << req_date << dendl; + return false; + } + *header_time = utime_t(timegm(&t), 0); } - header_time = utime_t(timegm(&t), 0); } map<string, string>& meta_map = info.x_meta_map; diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index c8bfbc92c06..33aa28414ca 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -7,7 +7,7 @@ void rgw_create_s3_canonical_header(const char *method, const char *content_md5, const char *content_type, const char *date, map<string, string>& meta_map, const char *request_uri, map<string, string>& sub_resources, string& dest_str); -bool rgw_create_s3_canonical_header(req_info& info, utime_t& header_time, string& dest, bool qsr); +bool rgw_create_s3_canonical_header(req_info& info, utime_t *header_time, string& dest, bool qsr); int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest); diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 64e052f517c..83151e727b2 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -104,6 +104,17 @@ req_info::req_info(CephContext *cct, struct RGWEnv *e) : env(e) { host = env->get("HTTP_HOST"); } +void req_info::rebuild_from(req_info& src) +{ + method = src.method; + script_uri = src.script_uri; + request_uri = src.request_uri; + host = src.host; + + x_meta_map = src.x_meta_map; + x_meta_map.erase("x-amz-date"); +} + req_state::req_state(CephContext *_cct, struct RGWEnv *e) : cct(_cct), cio(NULL), op(OP_UNKNOWN), bucket_cors(NULL), has_acl_header(false), diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 162e4932ff2..be91c85c571 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -667,6 +667,7 @@ struct req_info { string request_params; req_info(CephContext *cct, RGWEnv *_env); + void rebuild_from(req_info& src); }; /** Store all the state necessary to complete and respond to an HTTP request*/ diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index f51b5141afd..877d0e034a3 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -47,6 +47,10 @@ int RGWHTTPClient::process(const char *method, const char *url) for (iter = headers.begin(); iter != headers.end(); ++iter) { pair<string, string>& p = *iter; string val = p.first; + + if (strncmp(val.c_str(), "HTTP_", 5) == 0) { + val = val.substr(5); + } val.append(": "); val.append(p.second); h = curl_slist_append(h, val.c_str()); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index b038044ae0e..20a65631e63 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -866,7 +866,7 @@ void RGWCreateBucket::execute() } 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); + ret = store->rest_conn->forward(s->user.user_id, s->info); if (ret < 0) return; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 2db6f7be88b..148695f3183 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -290,6 +290,7 @@ struct RGWZoneParams { ::encode(user_swift_pool, bl); ::encode(user_uid_pool, bl); ::encode(name, bl); + ::encode(system_key, bl); ENCODE_FINISH(bl); } diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index c19a71be617..fd92c6e20fe 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -56,7 +56,7 @@ static void get_new_date_str(CephContext *cct, string& date_str) { utime_t tm = ceph_clock_now(cct); stringstream s; - tm.gmtime(s); + tm.asctime(s); date_str = s.str(); } @@ -105,24 +105,31 @@ int RGWRESTClient::execute(RGWAccessKey& key, const char *method, const char *re int RGWRESTClient::forward_request(RGWAccessKey& key, req_info& info) { - RGWEnv new_env = *info.env; /* copy environment */ - string date_str; get_new_date_str(cct, date_str); - new_env.set("HTTP_DATE", date_str.c_str()); - req_info new_info(info); - new_info.env = &new_env; + RGWEnv new_env; + req_info new_info(cct, &new_env); + new_info.rebuild_from(info); + + new_env.remove("HTTP_X_AMZ_DATE"); + new_env.set("HTTP_DATE", date_str.c_str()); map<string, string>& m = new_env.get_map(); + map<string, string>::iterator i; + for (i = m.begin(); i != m.end(); ++i) { + ldout(cct, 0) << "> " << i->first << " -> " << i->second << dendl; + } + string canonical_header; - utime_t header_time; - if (!rgw_create_s3_canonical_header(new_info, header_time, canonical_header, false)) { + if (!rgw_create_s3_canonical_header(new_info, NULL, canonical_header, false)) { ldout(cct, 0) << "failed to create canonical s3 header" << dendl; return -EINVAL; } + ldout(cct, 10) << "generated canonical header: " << canonical_header << dendl; + string digest; int ret = rgw_get_s3_header_digest(canonical_header, key.key, digest); if (ret < 0) { @@ -138,8 +145,19 @@ int RGWRESTClient::forward_request(RGWAccessKey& key, req_info& info) for (iter = m.begin(); iter != m.end(); ++iter) { headers.push_back(make_pair<string, string>(iter->first, iter->second)); } + + string new_url = url; + string& resource = new_info.request_uri; + string new_resource = resource; + if (new_url[new_url.size() - 1] == '/' && resource[0] == '/') { + new_url = new_url.substr(0, new_url.size() - 1); + } else if (resource[0] != '/') { + new_resource = "/"; + new_resource.append(resource); + } + new_url.append(new_resource); - int r = process(new_info.method, new_info.request_uri.c_str()); + int r = process(new_info.method, new_url.c_str()); if (r < 0) return r; diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index 274939a38b8..3c1d6c2234d 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -3,7 +3,8 @@ #define dout_subsys ceph_subsys_rgw -RGWRegionConnection::RGWRegionConnection(CephContext *_cct, RGWRados *store, RGWRegion& upstream) : cct(_cct) { +RGWRegionConnection::RGWRegionConnection(CephContext *_cct, RGWRados *store, RGWRegion& upstream) : cct(_cct) +{ list<string>::iterator iter; int i; for (i = 0, iter = upstream.endpoints.begin(); iter != upstream.endpoints.end(); ++iter, ++i) { @@ -25,7 +26,19 @@ int RGWRegionConnection::get_url(string& endpoint) return 0; } -int RGWRegionConnection::create_bucket(const string& uid, const string& bucket) { +int RGWRegionConnection::forward(const string& uid, req_info& info) +{ + string url; + int ret = get_url(url); + if (ret < 0) + return ret; + list<pair<string, string> > params; + RGWRESTClient client(cct, url, NULL, ¶ms); + return client.forward_request(key, info); +} + +int RGWRegionConnection::create_bucket(const string& uid, const string& bucket) +{ list<pair<string, string> > params; params.push_back(make_pair<string, string>("uid", uid)); params.push_back(make_pair<string, string>("bucket", bucket)); diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h index 0ddf4a15973..06657bf91e7 100644 --- a/src/rgw/rgw_rest_conn.h +++ b/src/rgw/rgw_rest_conn.h @@ -18,6 +18,7 @@ public: RGWRegionConnection(CephContext *_cct, RGWRados *store, RGWRegion& upstream); int get_url(string& endpoint); + int forward(const string& uid, req_info& info); int create_bucket(const string& uid, const string& bucket); }; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 00305b54d2b..f170953f8c4 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1956,7 +1956,7 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s) /* now verify signature */ string auth_hdr; - if (!rgw_create_s3_canonical_header(s->info, s->header_time, auth_hdr, qsr)) { + if (!rgw_create_s3_canonical_header(s->info, &s->header_time, auth_hdr, qsr)) { dout(10) << "failed to create auth header\n" << auth_hdr << dendl; return -EPERM; } |