From ce63faa91d1a0727295d7e07f576c81081f2b835 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 8 Jul 2016 16:18:50 +0530 Subject: [PATCH] rgw: Fix incorrect content length and range for zero sized objects during range requests Fixes: http://tracker.ceph.com/issues/16388 Signed-off-by: Pavan Rallabhandi --- src/rgw/rgw_rados.cc | 6 ++++++ src/rgw/rgw_rest.cc | 13 ++++++++++--- src/rgw/rgw_rest_swift.cc | 11 +++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 9e072479cd6bd..45ede31767067 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -8662,6 +8662,12 @@ int RGWRados::Object::Read::prepare(int64_t *pofs, int64_t *pend) } } + // for range requests with obj size 0 + if (!astate->size) { + end = astate->size - 1; + return -ERANGE; + } + if (pofs) *pofs = ofs; if (pend) diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 655bbd290e59e..7e69eda6c90f6 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -655,7 +655,9 @@ void end_header(struct req_state* s, RGWOp* op, const char *content_type, s->formatter->close_section(); } s->formatter->output_footer(); - dump_content_length(s, s->formatter->get_len()); + if (s->obj_size) { + dump_content_length(s, s->formatter->get_len()); + } } else { if (proposed_content_length != NO_CONTENT_LENGTH) { dump_content_length(s, proposed_content_length); @@ -769,8 +771,13 @@ void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, /* dumping range into temp buffer first, as libfcgi will fail to digest * %lld */ - snprintf(range_buf, sizeof(range_buf), "%lld-%lld/%lld", (long long)ofs, - (long long)end, (long long)total); + + if (!total) { + snprintf(range_buf, sizeof(range_buf), "*/%lld", (long long)total); + } else { + snprintf(range_buf, sizeof(range_buf), "%lld-%lld/%lld", (long long)ofs, + (long long)end, (long long)total); + } int r = STREAM_IO(s)->print("Content-Range: bytes %s\r\n", range_buf); if (r < 0) { ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl; diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index dc803265f78bc..503f331df1991 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -1205,17 +1205,20 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, set_req_state_err(s, (partial_content && !op_ret) ? STATUS_PARTIAL_CONTENT : op_ret); + dump_errno(s); - if (s->err.is_err()) { - end_header(s, NULL); - return 0; - } if (range_str) { dump_range(s, ofs, end, s->obj_size); } dump_content_length(s, total_len); + + if (s->err.is_err()) { + end_header(s, NULL); + return 0; + } + dump_last_modified(s, lastmod); { utime_t ut(lastmod);