Skip to content

Commit 6d3f88a

Browse files
committed
storage: Gate cache tag metadata behind feature flag
1 parent 1fd7ad6 commit 6d3f88a

4 files changed

Lines changed: 43 additions & 14 deletions

File tree

src/config/features.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@ pub struct FeaturesConfig {
1111
///
1212
/// Read from the `ZIP_ARCHIVES_ENABLED` environment variable.
1313
pub zip_archives_enabled: bool,
14+
15+
/// Emit CDN cache tags as storage metadata on uploads.
16+
///
17+
/// Read from the `CACHE_TAGS_ENABLED` environment variable.
18+
pub cache_tags_enabled: bool,
1419
}
1520

1621
impl FeaturesConfig {
1722
pub fn from_env() -> anyhow::Result<Self> {
1823
let index_include_pubtime = var_parsed("INDEX_INCLUDE_PUBTIME")?.unwrap_or(false);
1924
let zip_archives_enabled = var_parsed("ZIP_ARCHIVES_ENABLED")?.unwrap_or(false);
25+
let cache_tags_enabled = var_parsed("CACHE_TAGS_ENABLED")?.unwrap_or(false);
2026

2127
Ok(Self {
2228
index_include_pubtime,
2329
zip_archives_enabled,
30+
cache_tags_enabled,
2431
})
2532
}
2633
}

src/config/server.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ impl Server {
111111

112112
let max_blocking_threads = var_parsed("SERVER_THREADS")?;
113113

114-
let storage = StorageConfig::from_environment();
114+
let features = FeaturesConfig::from_env()?;
115+
116+
let mut storage = StorageConfig::from_environment();
117+
storage.cache_tags_enabled = features.cache_tags_enabled;
115118

116119
let domain_name = dotenvy::var("DOMAIN_NAME").unwrap_or_else(|_| "crates.io".into());
117120
let trustpub_audience = var("TRUSTPUB_AUDIENCE")?.unwrap_or_else(|| domain_name.clone());
@@ -147,7 +150,7 @@ impl Server {
147150
trustpub_audience,
148151
disable_token_creation,
149152
banner_message,
150-
features: FeaturesConfig::from_env()?,
153+
features,
151154
index_archive_url: var_parsed("GIT_ARCHIVE_REPO_URL")?,
152155
postgres_bin_dir: var_parsed("POSTGRES_BIN_DIR")?,
153156
})

src/storage.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const CACHE_CONTROL_OG_IMAGE: &str = "public,max-age=86400";
3131
pub struct StorageConfig {
3232
backend: StorageBackend,
3333
pub cdn_prefix: Option<String>,
34+
pub cache_tags_enabled: bool,
3435
}
3536

3637
#[derive(Debug)]
@@ -54,6 +55,7 @@ impl StorageConfig {
5455
Self {
5556
backend: StorageBackend::InMemory,
5657
cdn_prefix: None,
58+
cache_tags_enabled: false,
5759
}
5860
}
5961

@@ -87,6 +89,7 @@ impl StorageConfig {
8789
return Self {
8890
backend,
8991
cdn_prefix,
92+
cache_tags_enabled: false,
9093
};
9194
}
9295

@@ -101,6 +104,7 @@ impl StorageConfig {
101104
Self {
102105
backend,
103106
cdn_prefix: None,
107+
cache_tags_enabled: false,
104108
}
105109
}
106110
}
@@ -110,6 +114,7 @@ pub struct Storage {
110114
store: Arc<dyn ObjectStore>,
111115
index_store: Arc<dyn ObjectStore>,
112116
supports_attributes: bool,
117+
cache_tags_enabled: bool,
113118
}
114119

115120
impl Storage {
@@ -145,6 +150,7 @@ impl Storage {
145150
store: Arc::new(store),
146151
index_store: Arc::new(index_store),
147152
supports_attributes: true,
153+
cache_tags_enabled: config.cache_tags_enabled,
148154
}
149155
}
150156

@@ -173,6 +179,7 @@ impl Storage {
173179
store,
174180
index_store,
175181
supports_attributes: false,
182+
cache_tags_enabled: config.cache_tags_enabled,
176183
}
177184
}
178185

@@ -185,6 +192,7 @@ impl Storage {
185192
store: store.clone(),
186193
index_store: Arc::new(PrefixStore::new(store, "index")),
187194
supports_attributes: true,
195+
cache_tags_enabled: config.cache_tags_enabled,
188196
}
189197
}
190198
}
@@ -227,10 +235,7 @@ impl Storage {
227235
/// the key's intended attributes.
228236
#[instrument(skip(self, payload))]
229237
pub async fn upload(&self, key: &StorageKey<'_>, payload: PutPayload) -> Result<()> {
230-
let attributes = self
231-
.supports_attributes
232-
.then(|| key.attributes())
233-
.unwrap_or_default();
238+
let attributes = self.attributes(key);
234239

235240
let opts = attributes.into();
236241
self.store.put_opts(&key.path(), payload, opts).await?;
@@ -245,10 +250,7 @@ impl Storage {
245250
key: &StorageKey<'_>,
246251
mut reader: impl AsyncRead + Unpin,
247252
) -> anyhow::Result<()> {
248-
let attributes = self
249-
.supports_attributes
250-
.then(|| key.attributes())
251-
.unwrap_or_default();
253+
let attributes = self.attributes(key);
252254

253255
// Set up a streaming upload
254256
let mut writer = object_store::buffered::BufWriter::new(self.store.clone(), key.path())
@@ -267,6 +269,22 @@ impl Storage {
267269
Ok(())
268270
}
269271

272+
fn attributes(&self, key: &StorageKey<'_>) -> Attributes {
273+
if !self.supports_attributes {
274+
return Attributes::new();
275+
}
276+
277+
let mut attributes = key.attributes();
278+
279+
if self.cache_tags_enabled
280+
&& let Some(cache_tags) = key.cache_tags()
281+
{
282+
attributes.insert(Attribute::Metadata("cache-tags".into()), cache_tags.into());
283+
}
284+
285+
attributes
286+
}
287+
270288
#[instrument(skip(self))]
271289
pub async fn download_stream(
272290
&self,
@@ -471,9 +489,6 @@ impl<'a> StorageKey<'a> {
471489
if let Some(cache_control) = self.cache_control() {
472490
attributes.insert(Attribute::CacheControl, cache_control.into());
473491
}
474-
if let Some(cache_tags) = self.cache_tags() {
475-
attributes.insert(Attribute::Metadata("cache-tags".into()), cache_tags.into());
476-
}
477492
attributes
478493
}
479494
}
@@ -675,7 +690,9 @@ mod tests {
675690
async fn upload_sets_cache_tags_metadata() {
676691
use claims::{assert_none, assert_some_eq};
677692

678-
let s = Storage::from_config(&StorageConfig::in_memory());
693+
let mut config = StorageConfig::in_memory();
694+
config.cache_tags_enabled = true;
695+
let s = Storage::from_config(&config);
679696

680697
let key = StorageKey::for_crate_file("foo", "1.2.3");
681698
s.upload(&key, Bytes::new().into()).await.unwrap();

src/tests/util/test_app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ fn simple_config() -> config::Server {
564564

565565
let mut storage = StorageConfig::in_memory();
566566
storage.cdn_prefix = Some("static.crates.io".to_string());
567+
storage.cache_tags_enabled = true;
567568

568569
config::Server {
569570
base,
@@ -614,6 +615,7 @@ fn simple_config() -> config::Server {
614615
features: FeaturesConfig {
615616
index_include_pubtime: false,
616617
zip_archives_enabled: true,
618+
cache_tags_enabled: true,
617619
},
618620
index_archive_url: None,
619621
postgres_bin_dir: None,

0 commit comments

Comments
 (0)