]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: multiple fixes and cleanups
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 24 May 2013 06:14:35 +0000 (23:14 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 24 May 2013 06:14:35 +0000 (23:14 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_http_client.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_rest_s3.cc

index 89cc80d34218e8dbbff55235b859fc14ce727d6f..5a88d3b5e1a5666ab5a1c7489bdfd7e1832aea5a 100644 (file)
@@ -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_theader_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;
index c8bfbc92c060239519326f631a0eaa51c7fc4349..33aa28414ca7c8eab0bd5d590469f6abe498efc2 100644 (file)
@@ -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_theader_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);
 
 
index 64e052f517c1d3a61c8ebc4015e488374cddb627..83151e727b2d0333b8db3d5c7b645dd0dc3ee2a5 100644 (file)
@@ -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),
index 162e4932ff2e9e174c3427df77234a3780d74326..be91c85c5712b2a9457453cf669e7d531630ef81 100644 (file)
@@ -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*/
index f51b5141afdfce82fcc587097e01bed1b6d25aa7..877d0e034a3c2635c9b6eb8435f4797d6baae12d 100644 (file)
@@ -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());
index b038044ae0e9b13070126ca059f04b4fc38f8097..20a65631e63a24ecfcca6a8e80955b99e1b248fd 100644 (file)
@@ -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;
   }
index 2db6f7be88bd8cbc7c7f40e600fd2f2a4099b449..148695f3183cb4fcb7feb5c6c8d17afc95b5a156 100644 (file)
@@ -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);
   }
 
index c19a71be617f3417861cfe760d3e9cc85b37eac8..fd92c6e20fe23e966786949ac421cd056314af90 100644 (file)
@@ -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;
 
index 274939a38b81f2ed8b0c3a7e13b805c4f62c50a1..3c1d6c2234d76cbc5d68d578cd427673b9f5e49d 100644 (file)
@@ -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));
index 0ddf4a15973ca384cb90c6571eab4b19c8b44ac2..06657bf91e7d722c32893a3a949c7da12f6e458c 100644 (file)
@@ -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);
 
 };
index 00305b54d2b3301cbf9dfd9bea203e3342f62364..f170953f8c407d15917de7d30f6b0347a4f81980 100644 (file)
@@ -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;
   }