@@ -117,7 +117,9 @@ impl<T: ObjectStore> ObjectStore for PrefixStore<T> {
117117
118118 async fn get_opts ( & self , location : & Path , options : GetOptions ) -> Result < GetResult > {
119119 let full_path = self . full_path ( location) ;
120- self . inner . get_opts ( & full_path, options) . await
120+ let mut result = self . inner . get_opts ( & full_path, options) . await ?;
121+ result. meta = self . strip_meta ( result. meta ) ;
122+ Ok ( result)
121123 }
122124
123125 async fn get_ranges ( & self , location : & Path , ranges : & [ Range < u64 > ] ) -> Result < Vec < Bytes > > {
@@ -299,6 +301,26 @@ mod tests {
299301 assert_eq ! ( & * read_data, data)
300302 }
301303
304+ // Regression test for
305+ // https://github.com/apache/arrow-rs-object-store/issues/664:
306+ // head/get returned an ObjectMeta whose location still contained the
307+ // prefix, so round-tripping the returned location back into the store would
308+ // double-prefix it.
309+ #[ tokio:: test]
310+ async fn prefix_head_get_strip_prefix ( ) {
311+ let store = PrefixStore :: new ( InMemory :: new ( ) , "prefix" ) ;
312+ let path = Path :: from ( "test_file" ) ;
313+ store. put ( & path, "data" . into ( ) ) . await . unwrap ( ) ;
314+
315+ let head = store. head ( & path) . await . unwrap ( ) ;
316+ assert_eq ! ( head. location, path) ;
317+ let get = store. get ( & path) . await . unwrap ( ) ;
318+ assert_eq ! ( get. meta. location, path) ;
319+
320+ // The returned location must round-trip back into the same store.
321+ store. get ( & head. location ) . await . unwrap ( ) ;
322+ }
323+
302324 #[ tokio:: test]
303325 async fn prefix_multipart ( ) {
304326 let store = PrefixStore :: new ( InMemory :: new ( ) , "prefix" ) ;
0 commit comments