Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9198b6

Browse files
committed
feat: Implement basic registry index caching
Cache the registry index entries on the local filesystem in the same way the crate files are already cached. Put the registry index cache files under the "index/" subdirectory. TODO: Local cache invalidation and upstream synchronization.
1 parent ab301c9 commit a9198b6

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

src/file_cache.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::Path;
55

66
use log::error;
77

8-
use super::CrateInfo;
8+
use super::{CrateInfo, IndexEntry};
99

1010
/// Caches the crate package file on the local filesystem.
1111
pub fn cache_store_crate(dir: &Path, crate_info: &CrateInfo, data: &[u8]) {
@@ -25,3 +25,21 @@ pub fn cache_store_crate(dir: &Path, crate_info: &CrateInfo, data: &[u8]) {
2525
pub fn cache_fetch_crate(dir: &Path, crate_info: &CrateInfo) -> Option<Vec<u8>> {
2626
read(dir.join(crate_info.to_file_path())).ok()
2727
}
28+
29+
/// Caches the index entry file on the local filesystem.
30+
pub fn cache_store_index_entry(dir: &Path, entry: &IndexEntry, data: &[u8]) {
31+
let entry_file_path = dir.join(entry.to_file_path());
32+
33+
if let Err(e) = create_dir_all(entry_file_path.parent().unwrap()) {
34+
error!("cache: failed to create index directory: {e}");
35+
return;
36+
}
37+
38+
write(entry_file_path, data)
39+
.unwrap_or_else(|e| error!("cache: failed to write index entry file: {e}"));
40+
}
41+
42+
/// Fetches the cached index entry file from the local filesystem, if present.
43+
pub fn cache_fetch_index_entry(dir: &Path, entry: &IndexEntry) -> Option<Vec<u8>> {
44+
read(dir.join(entry.to_file_path())).ok()
45+
}

src/index_entry.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Registry index entry handling helpers
22
33
use std::fmt::{Display, Formatter, Result};
4+
use std::path::PathBuf;
45
use std::time::SystemTime;
56

67
use httpdate::{fmt_http_date, parse_http_date};
@@ -93,6 +94,12 @@ impl IndexEntry {
9394
),
9495
}
9596
}
97+
98+
/// Builds the relative index entry file path for cache storage.
99+
#[must_use]
100+
pub fn to_file_path(&self) -> PathBuf {
101+
PathBuf::from(self.to_index_url())
102+
}
96103
}
97104

98105
#[cfg(test)]

src/main.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ use url::Url;
2525

2626
use crate::config_json::{gen_config_json_file, is_config_json_url};
2727
use crate::crate_info::CrateInfo;
28-
use crate::file_cache::{cache_fetch_crate, cache_store_crate};
28+
use crate::file_cache::{
29+
cache_fetch_crate, cache_fetch_index_entry, cache_store_crate, cache_store_index_entry,
30+
};
2931
use crate::index_entry::IndexEntry;
3032

3133
/// Default listen address and port
@@ -79,6 +81,9 @@ struct ProxyConfig {
7981
/// External URL of this proxy server (defaults to [`DEFAULT_PROXY_URL`])
8082
proxy_url: Url,
8183

84+
/// Registry index cache directory (defaults to [`DEFAULT_CACHE_DIR`])
85+
index_dir: PathBuf,
86+
8287
/// Crate files cache directory (defaults to [`DEFAULT_CACHE_DIR`])
8388
crates_dir: PathBuf,
8489
}
@@ -295,6 +300,8 @@ fn forward_index_request(request: Request, entry: IndexEntry, config: ProxyConfi
295300
"fetch: successfully got index entry for {entry}",
296301
entry = response.entry
297302
);
303+
304+
cache_store_index_entry(&config.index_dir, &response.entry, &response.data);
298305
} else {
299306
debug!(
300307
"fetch: cached index entry for {entry} is up to date",
@@ -361,7 +368,20 @@ fn handle_index_request(request: Request, index_url: &str, config: &ProxyConfig)
361368
}
362369
}
363370

364-
forward_index_request(request, index_entry, config.clone());
371+
if let Some(data) = cache_fetch_index_entry(&config.index_dir, &index_entry) {
372+
debug!("proxy: local index cache hit for {index_entry}");
373+
374+
// TODO: Add cache control metadata.
375+
let response = IndexResponse {
376+
entry: index_entry,
377+
status: 200,
378+
data,
379+
};
380+
381+
send_index_entry_data_response(request, response);
382+
} else {
383+
forward_index_request(request, index_entry, config.clone());
384+
}
365385
}
366386

367387
/// Processes one HTTP GET request.
@@ -509,8 +529,14 @@ fn main() {
509529
info!("proxy: using proxy server URL: {proxy_url}");
510530

511531
let cache_dir = PathBuf::from(cache_dir_string);
532+
let index_dir = cache_dir.join("index");
512533
let crates_dir = cache_dir.join("crates");
513534

535+
info!(
536+
"cache: using index directory: {}",
537+
index_dir.to_string_lossy()
538+
);
539+
514540
info!(
515541
"cache: using crates directory: {}",
516542
crates_dir.to_string_lossy()
@@ -520,6 +546,7 @@ fn main() {
520546
index_url,
521547
upstream_url,
522548
proxy_url,
549+
index_dir,
523550
crates_dir,
524551
};
525552

0 commit comments

Comments
 (0)