]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_lc: replace strftime w/fmt and chrono:calendar 55644/head
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 19 Feb 2024 14:01:48 +0000 (09:01 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Tue, 12 Mar 2024 12:15:11 +0000 (08:15 -0400)
It's reliably claimed that std::strftime is not
mt-safe, and this would be a likely root cause of
intermittent scrambled expiration header output cases
that have been reported.

Fixes: https://tracker.ceph.com/issues/63973
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_lc.cc
src/test/rgw/test_rgw_lc.cc

index f98131a59e6af12eab98e891c2996e7437bf502b..18e2340c9d55992888355b9d18f4372277571f28 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab ft=cpp
 
+#include <fmt/chrono.h>
 #include <string.h>
 #include <iostream>
 #include <map>
@@ -2816,18 +2817,11 @@ std::string s3_expiration_header(
 
   // cond format header
   if (expiration_date && rule_id) {
-    // Fri, 23 Dec 2012 00:00:00 GMT
-    char exp_buf[100];
-    time_t exp = ceph::real_clock::to_time_t(*expiration_date);
-    if (std::strftime(exp_buf, sizeof(exp_buf),
-                     "%a, %d %b %Y %T %Z", std::gmtime(&exp))) {
-      hdr = fmt::format("expiry-date=\"{0}\", rule-id=\"{1}\"", exp_buf,
-                       *rule_id);
-    } else {
-      ldpp_dout(dpp, 0) << __func__ <<
-       "() strftime of life cycle expiration header failed"
-                       << dendl;
-    }
+    auto exp = ceph::real_clock::to_time_t(*expiration_date);
+    // Fri, 21 Dec 2012 00:00:00 GMT
+    auto exp_str = fmt::format("{:%a, %d %b %Y %T %Z}", fmt::gmtime(exp));
+    hdr = fmt::format("expiry-date=\"{0}\", rule-id=\"{1}\"", exp_str,
+                     *rule_id);
   }
 
   return hdr;
index d10b482cbfcec96f7426c4aa8ad08a661f967a9b..057deccbe207f2991cd5d150374024470762238e 100644 (file)
@@ -7,6 +7,7 @@
 #include <gtest/gtest.h>
 #include <string>
 #include <vector>
+#include <chrono>
 #include <stdexcept>
 
 static const char* xmldoc_1 =
@@ -107,6 +108,17 @@ TEST(TestLCFilterInvalidAnd, XMLDoc3)
   ASSERT_EQ(filter.get_flags(), uint32_t(LCFlagType::none));
 }
 
+TEST(ExpHdr, ReplaceStrftime)
+{
+  using namespace std::chrono;
+
+  constexpr auto dec21 = year(2012)/12/21;
+  auto exp = sys_days(dec21) + 9h + 13min + 7s ;
+  auto exp_str = fmt::format("{:%a, %d %b %Y %T %Z}", fmt::gmtime(exp));
+  std::cout << "exp_str: " << exp_str << std::endl;
+  ASSERT_EQ(exp_str, "Fri, 21 Dec 2012 09:13:07 GMT");
+}
+
 struct LCWorkTimeTests : ::testing::Test
 {
    CephContext* cct;