Skip to content

Commit

Permalink
rgw: Fix incorrect content length and range for zero sized objects du…
Browse files Browse the repository at this point in the history
…ring range requests

Fixes: http://tracker.ceph.com/issues/16388

Signed-off-by: Pavan Rallabhandi <PRallabhandi@walmartlabs.com>
  • Loading branch information
root committed Jul 16, 2016
1 parent 07387eb commit ce63faa
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
6 changes: 6 additions & 0 deletions src/rgw/rgw_rados.cc
Expand Up @@ -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)
Expand Down
13 changes: 10 additions & 3 deletions src/rgw/rgw_rest.cc
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 7 additions & 4 deletions src/rgw/rgw_rest_swift.cc
Expand Up @@ -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);
Expand Down

0 comments on commit ce63faa

Please sign in to comment.