summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcaleb miles <caselim@gmail.com>2012-10-11 13:00:48 -0400
committerYehuda Sadeh <yehuda@inktank.com>2012-10-23 10:44:18 -0700
commit7bb3504d3f0974e9863f536e9af0ce8889d6888f (patch)
treee23d63c9b437251b8efd01b75da824187fa40d06
parentca1e1776fced662dfde4c4aaec80d36eae03eaef (diff)
downloadceph-7bb3504d3f0974e9863f536e9af0ce8889d6888f.tar.gz
rgw: handle expiration and content length policy conditions.
Signed-off-by: caleb miles <caleb.miles@inktank.com> Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_op.cc8
-rw-r--r--src/rgw/rgw_op.h2
-rw-r--r--src/rgw/rgw_policy_s3.cc65
-rw-r--r--src/rgw/rgw_policy_s3.h12
-rw-r--r--src/rgw/rgw_rest_s3.cc6
-rw-r--r--src/rgw/rgw_rest_s3.h1
6 files changed, 85 insertions, 9 deletions
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index 9111c5f2998..0b1f7f6b502 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -1313,7 +1313,7 @@ void RGWPostObj::execute()
unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
MD5 hash;
bufferlist bl, aclbl;
- int len;
+ int len = 0;
ret = verify_params();
if (ret < 0)
@@ -1356,8 +1356,14 @@ void RGWPostObj::execute()
goto done;
ofs += len;
+
+ if (ofs > max_allowable_content_length)
+ goto done;
}
+ if (len < min_allowable_content_length)
+ goto done;
+
s->obj_size = ofs;
hash.Final(m);
diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h
index e41d189aa75..e9334384e7e 100644
--- a/src/rgw/rgw_op.h
+++ b/src/rgw/rgw_op.h
@@ -310,6 +310,8 @@ class RGWPostObj : public RGWOp {
friend class RGWPutObjProcessor;
protected:
+ int min_allowable_content_length;
+ int max_allowable_content_length;
int ret;
int len;
off_t ofs;
diff --git a/src/rgw/rgw_policy_s3.cc b/src/rgw/rgw_policy_s3.cc
index b0fc78524b2..dbe291c2cc7 100644
--- a/src/rgw/rgw_policy_s3.cc
+++ b/src/rgw/rgw_policy_s3.cc
@@ -105,13 +105,49 @@ RGWPolicy::~RGWPolicy()
}
}
+uint64_t RGWPolicy::get_current_epoch()
+{
+ uint64_t current_epoch = 0;
+ time_t local_time = ceph_clock_now(NULL).sec();
+ struct tm *gmt_time_struct = gmtime(&local_time);
+
+ current_epoch = timegm(gmt_time_struct);
+
+
+// string gmt_time_string = asctime(gmt_time_struct);
+
+// parse_date(gmt_time_string, &current_epoch, NULL, NULL);
+
+ return current_epoch;
+}
+
+void RGWPolicy::set_expires(utime_t& e)
+{
+ time_t e_time = e.sec();
+ struct tm *gmt_time_struct = gmtime(&e_time);
+ string gmt_time_string = asctime(gmt_time_struct);
+ parse_date(gmt_time_string, &expires, NULL, NULL);
+}
+
+void RGWPolicy::set_expires(string& e)
+{
+ parse_date(e, &expires, NULL, NULL);
+}
+
int RGWPolicy::add_condition(const string& op, const string& first, const string& second)
{
RGWPolicyCondition *cond = NULL;
- if (stringcasecmp(op, "eq") == 0)
+ if (stringcasecmp(op, "eq") == 0) {
cond = new RGWPolicyCondition_StrEqual;
- else if (stringcasecmp(op, "starts-with") == 0)
+ } else if (stringcasecmp(op, "starts-with") == 0) {
cond = new RGWPolicyCondition_StrStartsWith;
+ } else if (stringcasecmp(op, "content-length-range") == 0) {
+ stringstream min_string(first);
+ stringstream max_string(second);
+
+ if ( !(min_string >> min_length) || !(max_string >> max_length) )
+ return -EINVAL;
+ }
if (!cond)
return -EINVAL;
@@ -166,11 +202,31 @@ int RGWPolicy::from_json(bufferlist& bl)
if (!parser.parse(bl.c_str(), bl.length()))
return -EINVAL;
- JSONObjIter iter = parser.find_first("conditions");
+ // as no time was included in the request, we hope that the user has included a short timeout
+ JSONObjIter iter = parser.find_first("expiration");
if (iter.end())
- return 0;
+ return -EINVAL; // change to a "no expiration" error following S3
JSONObj *obj = *iter;
+ string expiration_string = obj->get_data();
+ set_expires(expiration_string);
+
+ uint64_t current_epoch = get_current_epoch();
+ if (current_epoch == 0) {
+ dout(0) << "NOTICE: failed to get current epoch!" << dendl;
+ return -EINVAL;
+ }
+
+ if (expires < current_epoch) {
+ dout(0) << "NOTICE: policy calculated as expired: " << expiration_string << dendl;
+ return -EINVAL; // change to condition about expired policy following S3
+ }
+
+ iter = parser.find_first("conditions");
+ if (iter.end())
+ return -EINVAL; // change to a "no conditions" error following S3
+
+ obj = *iter;
iter = obj->find_first();
for (; !iter.end(); ++iter) {
@@ -187,6 +243,7 @@ int RGWPolicy::from_json(bufferlist& bl)
}
if (i != 3 || !aiter.end()) /* we expect exactly 3 arguments here */
return -EINVAL;
+
add_condition(v[0], v[1], v[2]);
} else {
add_simple_check(child->get_name(), child->get_data());
diff --git a/src/rgw/rgw_policy_s3.h b/src/rgw/rgw_policy_s3.h
index 97cb3ed6a61..77fa13dc293 100644
--- a/src/rgw/rgw_policy_s3.h
+++ b/src/rgw/rgw_policy_s3.h
@@ -24,15 +24,21 @@ class RGWPolicyCondition;
class RGWPolicy {
- utime_t expires;
+ uint64_t expires;
std::list<RGWPolicyCondition *> conditions;
std::list<pair<std::string, std::string> > var_checks;
std::map<std::string, bool, ltstr_nocase> checked_vars;
public:
- RGWPolicy() {}
+ int min_length;
+ int max_length;
+
+ RGWPolicy() : expires(0), min_length(-1), max_length(-1) {}
~RGWPolicy();
- void set_expires(utime_t& e) { expires = e; }
+
+ uint64_t get_current_epoch();
+ void set_expires(utime_t& e);
+ void set_expires(string& e);
void set_var_checked(const std::string& var) {
checked_vars[var] = true;
diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc
index a6e9414a416..333a55c02fc 100644
--- a/src/rgw/rgw_rest_s3.cc
+++ b/src/rgw/rgw_rest_s3.cc
@@ -804,6 +804,11 @@ int RGWPostObj_ObjStore_S3::get_params()
if (r < 0)
return r;
+ if (post_policy.min_length > -1 && post_policy.max_length > -1) {
+ min_allowable_content_length = post_policy.min_length;
+ max_allowable_content_length = post_policy.max_length;
+ }
+
return 0;
}
@@ -867,7 +872,6 @@ int RGWPostObj_ObjStore_S3::get_policy()
ldout(s->cct, 0) << "POST policy: " << decoded_policy.c_str() << dendl;
- RGWPolicy post_policy;
int r = post_policy.from_json(decoded_policy);
if (r < 0) {
ldout(s->cct, 0) << "failed to parse policy" << dendl;
diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h
index de5edd26afa..25e67bbf52d 100644
--- a/src/rgw/rgw_rest_s3.h
+++ b/src/rgw/rgw_rest_s3.h
@@ -100,6 +100,7 @@ class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
bufferlist in_data;
map<string, post_form_part, const ltstr_nocase> parts;
RGWPolicyEnv env;
+ RGWPolicy post_policy;
int read_with_boundary(bufferlist& bl, uint64_t max, bool check_eol,
bool *reached_boundary,