summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2012-10-11 13:51:48 -0700
committerYehuda Sadeh <yehuda@inktank.com>2012-10-23 10:43:09 -0700
commitd7b59429f27111811c8161b0062285e4bad1df75 (patch)
tree16953a030df2a38afe770feac70b360cc316f9ab
parent3faf6ab56d573b9a77fec653e9c3c9a017af991d (diff)
downloadceph-d7b59429f27111811c8161b0062285e4bad1df75.tar.gz
rgw: return correct responses with POST
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_common.cc2
-rw-r--r--src/rgw/rgw_common.h1
-rw-r--r--src/rgw/rgw_rest.cc23
-rw-r--r--src/rgw/rgw_rest_s3.cc61
-rw-r--r--src/rgw/rgw_string.h67
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