Skip to content

Commit 95664ae

Browse files
authored
Merge pull request ceph#61290 from BBoozmen/wip-oozmen-67846
RGW/S3: truncate S3 LastModified response (timestamp) to exact seconds Reviewed-by: Casey Bodley <[email protected]>
2 parents a9b4eba + f6fb7df commit 95664ae

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

PendingReleaseNotes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
* use of tenant names instead of accounts in IAM policy documents,
1111
* interpretation of IAM policy without cross-account policy evaluation,
1212
* S3 API support for cross-tenant names such as `Bucket='tenant:bucketname'`
13+
* RGW: For compatibility with AWS S3, LastModified timestamps are now truncated
14+
to the second. Note that during upgrade, users may observe these timestamps
15+
moving backwards as a result.
1316

1417
* RBD: All Python APIs that produce timestamps now return "aware" `datetime`
1518
objects instead of "naive" ones (i.e. those including time zone information

src/rgw/rgw_rest.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,11 @@ void dump_time(req_state *s, const char *name, real_time t)
502502
s->formatter->dump_string(name, buf);
503503
}
504504

505+
void dump_time_exact_seconds(req_state *s, const char *name, real_time t)
506+
{
507+
dump_time(s, name, std::chrono::time_point_cast<std::chrono::seconds>(t));
508+
}
509+
505510
void dump_owner(req_state *s, const std::string& id, const string& name,
506511
const char *section)
507512
{

src/rgw/rgw_rest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ extern void dump_range(req_state* s, uint64_t ofs, uint64_t end,
914914
extern void dump_continue(req_state *s);
915915
extern void list_all_buckets_end(req_state *s);
916916
extern void dump_time(req_state *s, const char *name, real_time t);
917+
extern void dump_time_exact_seconds(req_state *s, const char *name, real_time t);
917918
extern std::string dump_time_to_str(const real_time& t);
918919
extern void dump_bucket_from_state(req_state *s);
919920
extern void dump_redirect(req_state *s, const std::string& redirect);

src/rgw/rgw_rest_s3.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ void RGWListBucket_ObjStore_S3::send_versioned_response()
18871887
}
18881888
s->formatter->dump_string("VersionId", version_id);
18891889
s->formatter->dump_bool("IsLatest", iter->is_current());
1890-
dump_time(s, "LastModified", iter->meta.mtime);
1890+
dump_time_exact_seconds(s, "LastModified", iter->meta.mtime);
18911891
if (!iter->is_delete_marker()) {
18921892
s->formatter->dump_format("ETag", "\"%s\"", iter->meta.etag.c_str());
18931893
s->formatter->dump_int("Size", iter->meta.accounted_size);
@@ -1980,7 +1980,7 @@ void RGWListBucket_ObjStore_S3::send_response()
19801980
s->formatter->open_object_section("dummy");
19811981
}
19821982
dump_urlsafe(s ,encode_key, "Key", key.name);
1983-
dump_time(s, "LastModified", iter->meta.mtime);
1983+
dump_time_exact_seconds(s, "LastModified", iter->meta.mtime);
19841984
s->formatter->dump_format("ETag", "\"%s\"", iter->meta.etag.c_str());
19851985
s->formatter->dump_int("Size", iter->meta.accounted_size);
19861986
auto& storage_class = rgw_placement_rule::get_canonical_storage_class(iter->meta.storage_class);
@@ -2054,7 +2054,7 @@ void RGWListBucket_ObjStore_S3v2::send_versioned_response()
20542054
}
20552055
s->formatter->dump_string("VersionId", version_id);
20562056
s->formatter->dump_bool("IsLatest", iter->is_current());
2057-
dump_time(s, "LastModified", iter->meta.mtime);
2057+
dump_time_exact_seconds(s, "LastModified", iter->meta.mtime);
20582058
if (!iter->is_delete_marker()) {
20592059
s->formatter->dump_format("ETag", "\"%s\"", iter->meta.etag.c_str());
20602060
s->formatter->dump_int("Size", iter->meta.accounted_size);
@@ -2124,7 +2124,7 @@ void RGWListBucket_ObjStore_S3v2::send_response()
21242124
rgw_obj_key key(iter->key);
21252125
s->formatter->open_array_section("Contents");
21262126
dump_urlsafe(s, encode_key, "Key", key.name);
2127-
dump_time(s, "LastModified", iter->meta.mtime);
2127+
dump_time_exact_seconds(s, "LastModified", iter->meta.mtime);
21282128
s->formatter->dump_format("ETag", "\"%s\"", iter->meta.etag.c_str());
21292129
s->formatter->dump_int("Size", iter->meta.accounted_size);
21302130
auto& storage_class = rgw_placement_rule::get_canonical_storage_class(iter->meta.storage_class);
@@ -3764,7 +3764,7 @@ void RGWCopyObj_ObjStore_S3::send_response()
37643764
send_partial_response(0);
37653765

37663766
if (op_ret == 0) {
3767-
dump_time(s, "LastModified", mtime);
3767+
dump_time_exact_seconds(s, "LastModified", mtime);
37683768
if (!etag.empty()) {
37693769
s->formatter->dump_format("ETag", "\"%s\"",etag.c_str());
37703770
}
@@ -4538,7 +4538,7 @@ void RGWListMultipart_ObjStore_S3::send_response()
45384538
rgw::sal::MultipartPart* part = iter->second.get();
45394539
s->formatter->open_object_section("Part");
45404540

4541-
dump_time(s, "LastModified", part->get_mtime());
4541+
dump_time_exact_seconds(s, "LastModified", part->get_mtime());
45424542

45434543
s->formatter->dump_unsigned("PartNumber", part->get_num());
45444544
s->formatter->dump_format("ETag", "\"%s\"", part->get_etag().c_str());

0 commit comments

Comments
 (0)