@@ -24,6 +24,8 @@ pub const HEADER_EXPIRATION: &str = "x-sn-expiration";
2424pub const HEADER_REDIRECT_TOMBSTONE : & str = "x-sn-redirect-tombstone" ;
2525/// The custom HTTP header that contains the object creation time.
2626pub const HEADER_TIME_CREATED : & str = "x-sn-time-created" ;
27+ /// The custom HTTP header that contains the object expiration time.
28+ pub const HEADER_TIME_EXPIRES : & str = "x-sn-time-expires" ;
2729/// The prefix for custom HTTP headers containing custom per-object metadata.
2830pub const HEADER_META_PREFIX : & str = "x-snme-" ;
2931
@@ -204,6 +206,13 @@ pub struct Metadata {
204206 #[ serde( skip_serializing_if = "Option::is_none" ) ]
205207 pub time_created : Option < SystemTime > ,
206208
209+ /// The expiration time of the object, if any, in accordance with its expiration policy.
210+ ///
211+ /// When using a Time To Idle expiration policy, this value will reflect the expiration
212+ /// timestamp present prior to the current access to the object.
213+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
214+ pub time_expires : Option < SystemTime > ,
215+
207216 /// The content type of the object, if known.
208217 pub content_type : Cow < ' static , str > ,
209218
@@ -261,6 +270,11 @@ impl Metadata {
261270 let time = parse_rfc3339 ( timestamp) ?;
262271 metadata. time_created = Some ( time) ;
263272 }
273+ HEADER_TIME_EXPIRES => {
274+ let timestamp = value. to_str ( ) ?;
275+ let time = parse_rfc3339 ( timestamp) ?;
276+ metadata. time_expires = Some ( time) ;
277+ }
264278 _ => {
265279 // customer-provided metadata
266280 if let Some ( name) = name. strip_prefix ( HEADER_META_PREFIX ) {
@@ -288,6 +302,7 @@ impl Metadata {
288302 compression,
289303 expiration_policy,
290304 time_created,
305+ time_expires,
291306 size : _,
292307 custom,
293308 } = self ;
@@ -319,6 +334,11 @@ impl Metadata {
319334 let timestamp = format_rfc3339_micros ( * time) ;
320335 headers. append ( name, timestamp. to_string ( ) . parse ( ) ?) ;
321336 }
337+ if let Some ( time) = time_expires {
338+ let name = HeaderName :: try_from ( format ! ( "{prefix}{HEADER_TIME_EXPIRES}" ) ) ?;
339+ let timestamp = format_rfc3339_micros ( * time) ;
340+ headers. append ( name, timestamp. to_string ( ) . parse ( ) ?) ;
341+ }
322342
323343 // customer-provided metadata
324344 for ( key, value) in custom {
@@ -343,6 +363,7 @@ impl Default for Metadata {
343363 is_redirect_tombstone : None ,
344364 expiration_policy : ExpirationPolicy :: Manual ,
345365 time_created : None ,
366+ time_expires : None ,
346367 content_type : DEFAULT_CONTENT_TYPE . into ( ) ,
347368 compression : None ,
348369 size : None ,
0 commit comments