From f3eb96457b193b1f5d79cf2b41a3cda690c0eab0 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 20 Jul 2010 12:12:39 -0700 Subject: [PATCH] rgw: fix content-length reporting and also some other various issues that came up while at it --- src/rgw/rgw_access.h | 3 +-- src/rgw/rgw_fs.cc | 11 ++++------- src/rgw/rgw_fs.h | 2 +- src/rgw/rgw_op.cc | 30 ++++++++++++++++++++---------- src/rgw/rgw_op.h | 5 ++++- src/rgw/rgw_rados.cc | 8 ++++---- src/rgw/rgw_rados.h | 2 +- src/rgw/rgw_rest.cc | 2 +- src/rgw/rgw_user.cc | 6 ++++-- 9 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/rgw/rgw_access.h b/src/rgw/rgw_access.h index ca83088aa345f..ad8a895affadd 100644 --- a/src/rgw/rgw_access.h +++ b/src/rgw/rgw_access.h @@ -111,7 +111,6 @@ public: * and if mtime is >= it fails. * if_match/nomatch: if non-NULL, compares the object's etag attr * to the string and, if it doesn't/does match, fails out. - * get_data: if true, the object's data/value will be read out, otherwise not * err: Many errors will result in this structure being filled * with extra informatin on the error. * Returns: -ERR# on failure, otherwise @@ -125,7 +124,7 @@ public: const time_t *unmod_ptr, const char *if_match, const char *if_nomatch, - bool get_data, + size_t *total_size, void **handle, struct rgw_err *err) = 0; diff --git a/src/rgw/rgw_fs.cc b/src/rgw/rgw_fs.cc index 609769ab4f0f8..044e761510f76 100644 --- a/src/rgw/rgw_fs.cc +++ b/src/rgw/rgw_fs.cc @@ -273,10 +273,11 @@ int RGWFS::copy_obj(std::string& id, std::string& dest_bucket, std::string& dest char *data; void *handle; off_t ofs = 0, end = -1; + size_t total_len; map attrset; ret = prepare_get_obj(src_bucket, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, - if_match, if_nomatch, true, &handle, err); + if_match, if_nomatch, &total_len, &handle, err); if (ret < 0) return ret; @@ -422,7 +423,7 @@ int RGWFS::prepare_get_obj(std::string& bucket, std::string& obj, const time_t *unmod_ptr, const char *if_match, const char *if_nomatch, - bool get_data, + size_t *total_size, void **handle, struct rgw_err *err) { @@ -505,11 +506,7 @@ int RGWFS::prepare_get_obj(std::string& bucket, std::string& obj, free(etag); - if (!get_data) { - r = max_len; - goto done; - } - + *total_size = (max_len > 0 ? max_len : 0); r = 0; done: return r; diff --git a/src/rgw/rgw_fs.h b/src/rgw/rgw_fs.h index e1f02a217bfd1..d35ab13e2be94 100644 --- a/src/rgw/rgw_fs.h +++ b/src/rgw/rgw_fs.h @@ -47,7 +47,7 @@ public: const time_t *unmod_ptr, const char *if_match, const char *if_nomatch, - bool get_data, + size_t *size, void **handle, struct rgw_err *err); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index e7830a5f5e50b..f50729d61dffe 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -14,7 +14,7 @@ using namespace std; -static int parse_range(const char *range, off_t ofs, off_t end) +static int parse_range(const char *range, off_t& ofs, off_t& end) { int r = -ERANGE; string s(range); @@ -32,9 +32,14 @@ static int parse_range(const char *range, off_t ofs, off_t end) ofs_str = s.substr(0, pos); end_str = s.substr(pos + 1); - ofs = atoll(ofs_str.c_str()); + if (ofs_str.length()) + ofs = atoll(ofs_str.c_str()); + + if (end_str.length()) end = atoll(end_str.c_str()); +cout << "parse_range ofs=" << ofs << " end=" << end << std::endl; + if (end < ofs) goto done; @@ -135,27 +140,32 @@ void RGWGetObj::execute() goto done; init_common(); - - len = rgwstore->prepare_get_obj(s->bucket_str, s->object_str, ofs, &end, &attrs, mod_ptr, - unmod_ptr, if_match, if_nomatch, get_data, &handle, &err); - - if (len < 0) { - ret = len; +cout << __func__ << ":" << __LINE__ << ": ofs=" << ofs << std::endl; + ret = rgwstore->prepare_get_obj(s->bucket_str, s->object_str, ofs, &end, &attrs, mod_ptr, + unmod_ptr, if_match, if_nomatch, &total_len, &handle, &err); + if (ret < 0) goto done; - } - if (!get_data) +cout << __func__ << ":" << __LINE__ << ": ofs=" << ofs << std::endl; + + if (!get_data || ofs > end) goto done; while (ofs <= end) { +cout << __func__ << ":" << __LINE__ << ": ofs=" << ofs << std::endl; + +cout << "RGWGetObj::execute():" << __LINE__ << ": len=" << len << std::endl; len = rgwstore->get_obj(&handle, s->bucket_str, s->object_str, &data, ofs, end); if (len < 0) { ret = len; goto done; } +cout << "RGWGetObj::execute():" << __LINE__ << ": len=" << len << std::endl; +cout << __func__ << ":" << __LINE__ << ": ofs=" << ofs << std::endl; ofs += len; send_response(handle); +cout << "RGWGetObj::execute():" << __LINE__ << ": len=" << len << std::endl; free(data); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index eb47b2e4274d7..054d6eaf3faaf 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -50,7 +50,8 @@ protected: const char *if_match; const char *if_nomatch; off_t ofs; - off_t len; + size_t len; + size_t total_len; off_t end; time_t mod_time; time_t unmod_time; @@ -71,9 +72,11 @@ public: RGWOp::init(s); ofs = 0; len = 0; + total_len = 0; end = -1; mod_ptr = NULL; unmod_ptr = NULL; + data = NULL; } void set_get_data(bool get_data) { this->get_data = get_data; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 89c2eac439caa..14bbbbd461ba4 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -343,6 +343,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d int ret, r; char *data; off_t ofs = 0, end = -1; + size_t total_len; map::iterator iter; cerr << "copy " << src_bucket << ":" << src_obj << " => " << dest_bucket << ":" << dest_obj << std::endl; @@ -351,7 +352,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d map attrset; ret = prepare_get_obj(src_bucket, src_obj, ofs, &end, &attrset, - mod_ptr, unmod_ptr, if_match, if_nomatch, true, &handle, err); + mod_ptr, unmod_ptr, if_match, if_nomatch, &total_len, &handle, err); if (ret < 0) return ret; @@ -512,7 +513,7 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, const time_t *unmod_ptr, const char *if_match, const char *if_nomatch, - bool get_data, + size_t *total_size, void **handle, struct rgw_err *err) { @@ -593,8 +594,7 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, if (*end < 0) *end = size - 1; - if (!get_data) - return size; + *total_size = (ofs <= *end ? *end + 1 - ofs : 0); return 0; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 88e208085e61f..f8bd34b42c72e 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -75,7 +75,7 @@ public: const time_t *unmod_ptr, const char *if_match, const char *if_nomatch, - bool get_data, + size_t *total_size, void **handle, struct rgw_err *err); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index f79ca08dc1a2e..f9dd055db30d4 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -202,7 +202,7 @@ int RGWGetObj_REST::send_response(void *handle) goto send_data; if (get_data && !ret) { - dump_content_length(s, len); + dump_content_length(s, total_len); } if (!ret) { map::iterator iter = attrs.find(RGW_ATTR_ETAG); diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 35375a6906763..2db5b5f4af08b 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -27,9 +27,10 @@ int rgw_get_user_info(string user_id, RGWUserInfo& info) struct rgw_err err; void *handle; off_t ofs = 0, end = -1; + size_t total_len; bufferlist::iterator iter; - ret = rgwstore->prepare_get_obj(ui_bucket, user_id, ofs, &end, NULL, NULL, NULL, NULL, NULL, true, &handle, &err); + ret = rgwstore->prepare_get_obj(ui_bucket, user_id, ofs, &end, NULL, NULL, NULL, NULL, NULL, &total_len, &handle, &err); if (ret < 0) return ret; do { @@ -117,9 +118,10 @@ int rgw_get_uid_by_email(string& email, string& user_id) void *handle; off_t ofs = 0, end = -1; bufferlist::iterator iter; + size_t total_len; ret = rgwstore->prepare_get_obj(ui_email_bucket, email, ofs, &end, NULL, NULL, - NULL, NULL, NULL, true, &handle, &err); + NULL, NULL, NULL, &total_len, &handle, &err); if (ret < 0) return ret; do { -- 2.39.5