diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2012-10-11 13:51:48 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2012-10-23 10:43:09 -0700 |
commit | d7b59429f27111811c8161b0062285e4bad1df75 (patch) | |
tree | 16953a030df2a38afe770feac70b360cc316f9ab | |
parent | 3faf6ab56d573b9a77fec653e9c3c9a017af991d (diff) | |
download | ceph-d7b59429f27111811c8161b0062285e4bad1df75.tar.gz |
rgw: return correct responses with POST
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/rgw_common.cc | 2 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 1 | ||||
-rw-r--r-- | src/rgw/rgw_rest.cc | 23 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 61 | ||||
-rw-r--r-- | src/rgw/rgw_string.h | 67 |
5 files changed, 117 insertions, 37 deletions
diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 07451e39393..089714fa354 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -81,7 +81,7 @@ is_clear() const bool rgw_err:: is_err() const { - return !(http_ret >= 200 && http_ret <= 299); + return !(http_ret >= 200 && http_ret <= 399); } diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 0ebaa9fa4e0..d58bf857445 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -568,6 +568,7 @@ struct req_state { ceph::Formatter *formatter; string decoded_uri; string request_uri; + string script_uri; string request_params; const char *host; const char *method; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 1099d5ee479..03638f45099 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -370,14 +370,9 @@ int RESTArgs::get_uint64(struct req_state *s, const string& name, uint64_t def_v return 0; } - char *end; - - *val = (uint64_t)strtoull(sval.c_str(), &end, 10); - if (*val == ULLONG_MAX) - return -EINVAL; - - if (*end) - return -EINVAL; + int r = stringtoull(sval, val); + if (r < 0) + return r; return 0; } @@ -395,14 +390,9 @@ int RESTArgs::get_int64(struct req_state *s, const string& name, int64_t def_val return 0; } - char *end; - - *val = (int64_t)strtoll(sval.c_str(), &end, 10); - if (*val == LLONG_MAX) - return -EINVAL; - - if (*end) - return -EINVAL; + int r = stringtoll(sval, val); + if (r < 0) + return r; return 0; } @@ -1047,6 +1037,7 @@ RGWRESTMgr::~RGWRESTMgr() int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio) { s->cio = cio; + s->script_uri = s->env->get("SCRIPT_URI"); s->request_uri = s->env->get("REQUEST_URI"); int pos = s->request_uri.find('?'); if (pos >= 0) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 97edfb94eb5..4ffa7a1d47a 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -928,36 +928,57 @@ void RGWPostObj_ObjStore_S3::send_response() { if (ret == 0 && parts.count("success_action_redirect")) { string success_action_redirect; + part_str("success_action_redirect", &success_action_redirect); - if (check_utf8(success_action_redirect.c_str(), success_action_redirect.size()) == 0) { - dump_redirect(s, success_action_redirect); - set_req_state_err(s, STATUS_REDIRECT); - dump_errno(s); - end_header(s, "text/plain"); - return; + + int r = check_utf8(success_action_redirect.c_str(), success_action_redirect.size()); + if (r < 0) { + ret = r; + goto done; } + dump_redirect(s, success_action_redirect); + ret = STATUS_REDIRECT; } else if (ret == 0 && parts.count("success_action_status")) { string status_string; + uint32_t status_int; + part_str("success_action_status", &status_string); - int status_int; - if ( !(istringstream(status_string) >> status_int) ) - status_int = 200; - dump_errno(s, status_int); - } else { - dump_errno(s); + int r = stringtoul(status_string, &status_int); + if (r < 0) { + ret = r; + goto done; + } + + switch (status_int) { + case 200: + break; + case 201: + ret = STATUS_CREATED; + break; + default: + ret = STATUS_NO_CONTENT; + break; + } } - set_req_state_err(s, ret); +done: + if (ret == STATUS_CREATED) { + s->formatter->open_object_section("PostResponse"); + if (g_conf->rgw_dns_name.length()) + s->formatter->dump_format("Location", "%s/%s", s->script_uri.c_str(), s->object_str.c_str()); + s->formatter->dump_string("Bucket", s->bucket_name); + s->formatter->dump_string("Key", s->object_str.c_str()); + s->formatter->close_section(); + } + set_req_state_err(s, ret); + dump_errno(s); + dump_content_length(s, s->formatter->get_len()); end_header(s); - if (ret < 0) + if (ret != STATUS_CREATED) return; -#if 0 - dump_common_s3_headers(s, etag.c_str(), 0, "close"); - dump_bucket_from_state(s); - dump_object_from_state(s); - dump_uri_from_state(s); -#endif + + rgw_flush_formatter_and_reset(s, s->formatter); } diff --git a/src/rgw/rgw_string.h b/src/rgw/rgw_string.h index bbd2c67b6c9..3c881a10a91 100644 --- a/src/rgw/rgw_string.h +++ b/src/rgw/rgw_string.h @@ -1,6 +1,9 @@ #ifndef CEPH_RGW_STRING_H #define CEPH_RGW_STRING_H +#include <stdlib.h> +#include <limits.h> + struct ltstr_nocase { bool operator()(const string& s1, const string& s2) const @@ -24,4 +27,68 @@ static inline int stringcasecmp(const string& s1, int ofs, int size, const strin return strncasecmp(s1.c_str() + ofs, s2.c_str(), size); } +static inline int stringtoll(const string& s, int64_t *val) +{ + char *end; + + long long result = strtoll(s.c_str(), &end, 10); + if (result == LLONG_MAX) + return -EINVAL; + + if (*end) + return -EINVAL; + + *val = (int64_t)result; + + return 0; +} + +static inline int stringtoull(const string& s, uint64_t *val) +{ + char *end; + + unsigned long long result = strtoull(s.c_str(), &end, 10); + if (result == ULLONG_MAX) + return -EINVAL; + + if (*end) + return -EINVAL; + + *val = (uint64_t)result; + + return 0; +} + +static inline int stringtol(const string& s, int32_t *val) +{ + char *end; + + long result = strtol(s.c_str(), &end, 10); + if (result == LONG_MAX) + return -EINVAL; + + if (*end) + return -EINVAL; + + *val = (int32_t)result; + + return 0; +} + +static inline int stringtoul(const string& s, uint32_t *val) +{ + char *end; + + unsigned long result = strtoul(s.c_str(), &end, 10); + if (result == ULONG_MAX) + return -EINVAL; + + if (*end) + return -EINVAL; + + *val = (uint32_t)result; + + return 0; +} + #endif |