summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-05-23 23:14:35 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-05-23 23:14:35 -0700
commit580a08c6d658dfbcba13d8e92ebbfca8297a2dee (patch)
tree3e97d9d477eeea81d33bdf00568d4a12fef5be4d
parent2655c1e459197e9c4d863f29ee05a95f9f1f1129 (diff)
downloadceph-580a08c6d658dfbcba13d8e92ebbfca8297a2dee.tar.gz
rgw: multiple fixes and cleanups
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_auth_s3.cc22
-rw-r--r--src/rgw/rgw_auth_s3.h2
-rw-r--r--src/rgw/rgw_common.cc11
-rw-r--r--src/rgw/rgw_common.h1
-rw-r--r--src/rgw/rgw_http_client.cc4
-rw-r--r--src/rgw/rgw_op.cc2
-rw-r--r--src/rgw/rgw_rados.h1
-rw-r--r--src/rgw/rgw_rest_client.cc36
-rw-r--r--src/rgw/rgw_rest_conn.cc17
-rw-r--r--src/rgw/rgw_rest_conn.h1
-rw-r--r--src/rgw/rgw_rest_s3.cc2
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, &params);
+ 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;
}