plus many fixes.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
rgw/rgw_cors_swift.h\
rgw/rgw_string.h\
rgw/rgw_formats.h\
- rgw/rgw_html_errors.h\
+ rgw/rgw_http_errors.h\
rgw/rgw_log.h\
rgw/rgw_multi.h\
rgw/rgw_policy_s3.h\
+++ /dev/null
-#ifndef RGW_HTML_ERRORS_H_
-#define RGW_HTML_ERRORS_H_
-
-#include "rgw_common.h"
-
-struct rgw_html_errors {
- int err_no;
- int http_ret;
- const char *s3_code;
-};
-
-const static struct rgw_html_errors RGW_HTML_ERRORS[] = {
- { 0, 200, "" },
- { STATUS_CREATED, 201, "Created" },
- { STATUS_ACCEPTED, 202, "Accepted" },
- { STATUS_NO_CONTENT, 204, "NoContent" },
- { STATUS_PARTIAL_CONTENT, 206, "" },
- { ERR_PERMANENT_REDIRECT, 301, "PermanentRedirect" },
- { STATUS_REDIRECT, 303, "" },
- { ERR_NOT_MODIFIED, 304, "NotModified" },
- { EINVAL, 400, "InvalidArgument" },
- { ERR_INVALID_REQUEST, 400, "InvalidRequest" },
- { ERR_INVALID_DIGEST, 400, "InvalidDigest" },
- { ERR_BAD_DIGEST, 400, "BadDigest" },
- { ERR_INVALID_BUCKET_NAME, 400, "InvalidBucketName" },
- { ERR_INVALID_OBJECT_NAME, 400, "InvalidObjectName" },
- { ERR_UNRESOLVABLE_EMAIL, 400, "UnresolvableGrantByEmailAddress" },
- { ERR_INVALID_PART, 400, "InvalidPart" },
- { ERR_INVALID_PART_ORDER, 400, "InvalidPartOrder" },
- { ERR_REQUEST_TIMEOUT, 400, "RequestTimeout" },
- { ERR_TOO_LARGE, 400, "EntityTooLarge" },
- { ERR_TOO_SMALL, 400, "EntityTooSmall" },
- { ERR_TOO_MANY_BUCKETS, 400, "TooManyBuckets" },
- { ERR_LENGTH_REQUIRED, 411, "MissingContentLength" },
- { EACCES, 403, "AccessDenied" },
- { EPERM, 403, "AccessDenied" },
- { ERR_USER_SUSPENDED, 403, "UserSuspended" },
- { ERR_REQUEST_TIME_SKEWED, 403, "RequestTimeTooSkewed" },
- { ENOENT, 404, "NoSuchKey" },
- { ERR_NO_SUCH_BUCKET, 404, "NoSuchBucket" },
- { ERR_NO_SUCH_UPLOAD, 404, "NoSuchUpload" },
- { ERR_NOT_FOUND, 404, "Not Found"},
- { ERR_METHOD_NOT_ALLOWED, 405, "MethodNotAllowed" },
- { ETIMEDOUT, 408, "RequestTimeout" },
- { EEXIST, 409, "BucketAlreadyExists" },
- { ENOTEMPTY, 409, "BucketNotEmpty" },
- { ERR_PRECONDITION_FAILED, 412, "PreconditionFailed" },
- { ERANGE, 416, "InvalidRange" },
- { ERR_UNPROCESSABLE_ENTITY, 422, "UnprocessableEntity" },
- { ERR_INTERNAL_ERROR, 500, "InternalError" },
-};
-
-const static struct rgw_html_errors RGW_HTML_SWIFT_ERRORS[] = {
- { EACCES, 401, "AccessDenied" },
- { EPERM, 401, "AccessDenied" },
- { ERR_USER_SUSPENDED, 401, "UserSuspended" },
- { ERR_INVALID_UTF8, 412, "Invalid UTF8" },
- { ERR_BAD_URL, 412, "Bad URL" },
-};
-
-#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
-
-static inline const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
-{
- for (int i = 0; i < len; ++i, ++errs) {
- if (err_no == errs->err_no)
- return errs;
- }
- return NULL;
-}
-
-
-
-#endif
return len;
}
-int RGWHTTPClient::process(const string& url)
+int RGWHTTPClient::process(const char *method, const char *url)
{
int ret = 0;
CURL *curl_handle;
h = curl_slist_append(h, val.c_str());
}
- curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, method);
+ curl_easy_setopt(curl_handle, CURLOPT_URL, url);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, read_http_header);
virtual int read_header(void *ptr, size_t len) { return 0; }
virtual int read_data(void *ptr, size_t len) { return 0; }
- int process(const string& url);
+ int process(const char *method, const char *url);
+ int process(const char *url) { return process("GET", url); }
};
#endif
--- /dev/null
+#ifndef RGW_HTTP_ERRORS_H_
+#define RGW_HTTP_ERRORS_H_
+
+#include "rgw_common.h"
+
+struct rgw_http_errors {
+ int err_no;
+ int http_ret;
+ const char *s3_code;
+};
+
+const static struct rgw_http_errors RGW_HTTP_ERRORS[] = {
+ { 0, 200, "" },
+ { STATUS_CREATED, 201, "Created" },
+ { STATUS_ACCEPTED, 202, "Accepted" },
+ { STATUS_NO_CONTENT, 204, "NoContent" },
+ { STATUS_PARTIAL_CONTENT, 206, "" },
+ { ERR_PERMANENT_REDIRECT, 301, "PermanentRedirect" },
+ { STATUS_REDIRECT, 303, "" },
+ { ERR_NOT_MODIFIED, 304, "NotModified" },
+ { EINVAL, 400, "InvalidArgument" },
+ { ERR_INVALID_REQUEST, 400, "InvalidRequest" },
+ { ERR_INVALID_DIGEST, 400, "InvalidDigest" },
+ { ERR_BAD_DIGEST, 400, "BadDigest" },
+ { ERR_INVALID_BUCKET_NAME, 400, "InvalidBucketName" },
+ { ERR_INVALID_OBJECT_NAME, 400, "InvalidObjectName" },
+ { ERR_UNRESOLVABLE_EMAIL, 400, "UnresolvableGrantByEmailAddress" },
+ { ERR_INVALID_PART, 400, "InvalidPart" },
+ { ERR_INVALID_PART_ORDER, 400, "InvalidPartOrder" },
+ { ERR_REQUEST_TIMEOUT, 400, "RequestTimeout" },
+ { ERR_TOO_LARGE, 400, "EntityTooLarge" },
+ { ERR_TOO_SMALL, 400, "EntityTooSmall" },
+ { ERR_TOO_MANY_BUCKETS, 400, "TooManyBuckets" },
+ { ERR_LENGTH_REQUIRED, 411, "MissingContentLength" },
+ { EACCES, 403, "AccessDenied" },
+ { EPERM, 403, "AccessDenied" },
+ { ERR_USER_SUSPENDED, 403, "UserSuspended" },
+ { ERR_REQUEST_TIME_SKEWED, 403, "RequestTimeTooSkewed" },
+ { ENOENT, 404, "NoSuchKey" },
+ { ERR_NO_SUCH_BUCKET, 404, "NoSuchBucket" },
+ { ERR_NO_SUCH_UPLOAD, 404, "NoSuchUpload" },
+ { ERR_NOT_FOUND, 404, "Not Found"},
+ { ERR_METHOD_NOT_ALLOWED, 405, "MethodNotAllowed" },
+ { ETIMEDOUT, 408, "RequestTimeout" },
+ { EEXIST, 409, "BucketAlreadyExists" },
+ { ENOTEMPTY, 409, "BucketNotEmpty" },
+ { ERR_PRECONDITION_FAILED, 412, "PreconditionFailed" },
+ { ERANGE, 416, "InvalidRange" },
+ { ERR_UNPROCESSABLE_ENTITY, 422, "UnprocessableEntity" },
+ { ERR_INTERNAL_ERROR, 500, "InternalError" },
+};
+
+const static struct rgw_http_errors RGW_HTTP_SWIFT_ERRORS[] = {
+ { EACCES, 401, "AccessDenied" },
+ { EPERM, 401, "AccessDenied" },
+ { ERR_USER_SUSPENDED, 401, "UserSuspended" },
+ { ERR_INVALID_UTF8, 412, "Invalid UTF8" },
+ { ERR_BAD_URL, 412, "Bad URL" },
+};
+
+#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
+
+static inline const struct rgw_http_errors *search_err(int err_no, const struct rgw_http_errors *errs, int len)
+{
+ for (int i = 0; i < len; ++i, ++errs) {
+ if (err_no == errs->err_no)
+ return errs;
+ }
+ return NULL;
+}
+
+
+static inline int rgw_http_error_to_errno(int http_err)
+{
+ if (http_err >= 200 && http_err <= 299)
+ return 0;
+ switch (http_err) {
+ case 400:
+ return -EINVAL;
+ case 401:
+ return -EPERM;
+ case 403:
+ return -EACCES;
+ case 404:
+ return -ENOENT;
+ default:
+ return -EIO;
+ }
+
+ return 0; /* unreachable */
+}
+
+
+#endif
if (!store->region.is_master) {
if (store->region.api_name != location_constraint) {
- ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << dendl;
+ ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << " (" << store->region.api_name << ")" << dendl;
ret = -EINVAL;
return;
}
+
+ 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);
+ if (ret < 0)
+ return;
}
s->bucket_owner.set_id(s->user.user_id);
delete gc;
gc = NULL;
}
+ delete rest_conn;
}
/**
ldout(cct, 0) << "WARNING: cannot read region map" << dendl;
} else {
string master_region = region_map.master_region;
+ if (master_region.empty()) {
+ lderr(cct) << "ERROR: region map does not specify master region" << dendl;
+ return -EINVAL;
+ }
map<string, RGWRegion>::iterator iter = region_map.regions.find(master_region);
if (iter == region_map.regions.end()) {
lderr(cct) << "ERROR: bad region map: inconsistent master region" << dendl;
void set_req_state_err(struct req_state *s, int err_no)
{
- const struct rgw_html_errors *r;
+ const struct rgw_http_errors *r;
if (err_no < 0)
err_no = -err_no;
s->err.ret = err_no;
if (s->prot_flags & RGW_REST_SWIFT) {
- r = search_err(err_no, RGW_HTML_SWIFT_ERRORS, ARRAY_LEN(RGW_HTML_SWIFT_ERRORS));
+ r = search_err(err_no, RGW_HTTP_SWIFT_ERRORS, ARRAY_LEN(RGW_HTTP_SWIFT_ERRORS));
if (r) {
s->err.http_ret = r->http_ret;
s->err.s3_code = r->s3_code;
return;
}
}
- r = search_err(err_no, RGW_HTML_ERRORS, ARRAY_LEN(RGW_HTML_ERRORS));
+ r = search_err(err_no, RGW_HTTP_ERRORS, ARRAY_LEN(RGW_HTTP_ERRORS));
if (r) {
s->err.http_ret = r->http_ret;
s->err.s3_code = r->s3_code;
#include "rgw_common.h"
#include "rgw_rest_client.h"
+#include "rgw_http_errors.h"
#include "common/ceph_crypto_cms.h"
#include "common/armor.h"
}
if (*s == '\n') {
*p = '\0';
- ldout(cct, 10) << "os_auth:" << line << dendl;
+ ldout(cct, 10) << "received header:" << line << dendl;
// TODO: fill whatever data required here
char *l = line;
char *tok = strsep(&l, " \t:");
- if (tok) {
- while (l && *l == ' ')
+ if (tok && l) {
+ while (*l == ' ')
l++;
- if (strcmp(tok, "HTTP") == 0) {
+ if (strcmp(tok, "HTTP") == 0 || strncmp(tok, "HTTP/", 5) == 0) {
status = atoi(l);
} else {
/* convert header field name to upper case */
return 0;
}
-int RGWRESTClient::execute(RGWAccessKey& key, const string& method, const string& resource)
+int RGWRESTClient::execute(RGWAccessKey& key, const char *method, const char *resource)
{
string new_url = url;
string new_resource = resource;
list<pair<string, string> >::iterator iter;
for (iter = params.begin(); iter != params.end(); ++iter) {
+ if (iter != params.begin())
+ new_url.append("?");
new_url.append(iter->first + "=" + iter->second);
}
}
string date_str = s.str();
headers.push_back(make_pair<string, string>("HTTP_DATE", date_str));
- string canonical_header = method + " " +
+ string canonical_header = string(method) + " " +
"\n" + /* CONTENT_MD5 */
"\n" + /* CONTENT_TYPE */
date_str + "\n" +
string auth_hdr = "AWS " + key.id + ":" + b64;
headers.push_back(make_pair<string, string>("AUTHORIZATION", auth_hdr));
- return process(new_url);
+ int r = process(method, new_url.c_str());
+ if (r < 0)
+ return r;
+
+ return rgw_http_error_to_errno(status);
}
map<string, string> out_headers;
list<pair<string, string> > params;
-
- RGWRESTClient() : cct(NULL), status(0) {}
public:
- RGWRESTClient(CephContext *_cct, string& _url,
- list<pair<string, string> > *_headers, list<pair<string, string> > *_params) : cct(_cct), url(_url) {
+ RGWRESTClient(CephContext *_cct, string& _url, list<pair<string, string> > *_headers,
+ list<pair<string, string> > *_params) : cct(_cct), status(0), url(_url) {
if (_headers)
headers = *_headers;
int read_header(void *ptr, size_t len);
- int execute(RGWAccessKey& key, const string& method, const string& resource);
+ int execute(RGWAccessKey& key, const char *method, const char *resource);
};
s->formatter->close_section();
}
-void rgw_get_errno_s3(rgw_html_errors *e , int err_no)
+void rgw_get_errno_s3(rgw_http_errors *e , int err_no)
{
- const struct rgw_html_errors *r;
- r = search_err(err_no, RGW_HTML_ERRORS, ARRAY_LEN(RGW_HTML_ERRORS));
+ const struct rgw_http_errors *r;
+ r = search_err(err_no, RGW_HTTP_ERRORS, ARRAY_LEN(RGW_HTTP_ERRORS));
if (r) {
e->http_ret = r->http_ret;
s->formatter->dump_string("Key", result.first);
s->formatter->close_section();
} else if (result.first < 0) {
- struct rgw_html_errors r;
+ struct rgw_http_errors r;
int err_no;
s->formatter->open_object_section("Error");
#define TIME_BUF_SIZE 128
#include "rgw_op.h"
-#include "rgw_html_errors.h"
+#include "rgw_http_errors.h"
#include "rgw_acl_s3.h"
#include "rgw_policy_s3.h"
#define RGW_AUTH_GRACE_MINS 15
-void rgw_get_errno_s3(struct rgw_html_errors *e, int err_no);
+void rgw_get_errno_s3(struct rgw_http_errors *e, int err_no);
class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
{
req.append_header("X-Auth-Token", g_conf->rgw_keystone_admin_token);
- int ret = req.process(url);
+ int ret = req.process(url.c_str());
if (ret < 0)
return ret;
validate.append_header("X-Auth-Token", g_conf->rgw_keystone_admin_token);
- int ret = validate.process(url);
+ int ret = validate.process(url.c_str());
if (ret < 0)
return ret;
}