Skip to content

Commit e583414

Browse files
committed
feat(serve): serve blog assets
1 parent cd7779d commit e583414

File tree

1 file changed

+56
-3
lines changed

1 file changed

+56
-3
lines changed

crates/rari-cli/serve.rs

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ use rari_doc::contributors::contributors_txt;
1515
use rari_doc::error::DocError;
1616
use rari_doc::issues::{to_display_issues, IN_MEMORY, ISSUE_COUNTER_F};
1717
use rari_doc::pages::json::BuiltPage;
18-
use rari_doc::pages::page::{Page, PageBuilder, PageLike};
18+
use rari_doc::pages::page::{Page, PageBuilder, PageCategory, PageLike};
1919
use rari_doc::pages::templates::DocPage;
2020
use rari_doc::pages::types::doc::Doc;
2121
use rari_doc::reader::read_docs_parallel;
22+
use rari_doc::resolve::{url_meta_from, UrlMeta};
2223
use rari_tools::error::ToolError;
2324
use rari_tools::fix::issues::fix_page;
24-
use rari_types::globals::{self, content_root, content_translated_root};
25+
use rari_types::globals::{self, blog_root, content_root, content_translated_root};
2526
use rari_types::locale::Locale;
2627
use rari_types::Popularities;
2728
use rari_utils::io::read_to_string;
@@ -32,6 +33,10 @@ use tracing::{error, span, Level};
3233

3334
static REQ_COUNTER: AtomicU64 = AtomicU64::new(1);
3435

36+
static ASSET_EXTENSION: &[&str] = &[
37+
"gif", "jpeg", "jpg", "mp3", "mp4", "ogg", "png", "svg", "webm", "webp", "woff2",
38+
];
39+
3540
tokio::task_local! {
3641
static SERVER_ISSUE_COUNTER: AtomicI64;
3742
}
@@ -49,8 +54,16 @@ struct SearchItem {
4954
}
5055

5156
async fn handler(req: Request) -> Response<Body> {
52-
if req.uri().path().ends_with("/contributors.txt") {
57+
let path = req.uri().path();
58+
if path.ends_with("/contributors.txt") {
5359
get_contributors_handler(req).await.into_response()
60+
} else if ASSET_EXTENSION.contains(
61+
&path
62+
.rsplit_once('.')
63+
.map(|(_, ext)| ext)
64+
.unwrap_or_default(),
65+
) {
66+
get_file_handler(req).await.into_response()
5467
} else {
5568
get_json_handler(req).await.into_response()
5669
}
@@ -81,6 +94,46 @@ async fn wrapped_fix_issues(
8194
.await
8295
}
8396

97+
async fn get_file_handler(req: Request) -> Result<Response, AppError> {
98+
let url = req.uri().path();
99+
tracing::info!("(asset) {}", url);
100+
let UrlMeta {
101+
page_category,
102+
slug,
103+
..
104+
} = url_meta_from(url)?;
105+
106+
// Blog author avatars are special.
107+
if matches!(page_category, PageCategory::BlogPost) && slug.starts_with("author/") {
108+
if let Some(blog_root_parent) = blog_root() {
109+
let path = blog_root_parent
110+
.join("authors")
111+
.join(slug.strip_prefix("author/").unwrap());
112+
return Ok(ServeFile::new(path).oneshot(req).await.into_response());
113+
}
114+
}
115+
116+
if let Some(last_slash) = url.rfind('/') {
117+
let doc_url = &url[..(if matches!(
118+
page_category,
119+
PageCategory::BlogPost | PageCategory::Curriculum
120+
) {
121+
// Add trailing slash for paths that require it.
122+
last_slash + 1
123+
} else {
124+
last_slash
125+
})];
126+
127+
let file_name = &url[last_slash + 1..];
128+
let page = Page::from_url_with_fallback(doc_url)?;
129+
let path = page.full_path().with_file_name(file_name);
130+
131+
return Ok(ServeFile::new(path).oneshot(req).await.into_response());
132+
}
133+
134+
Ok((StatusCode::BAD_REQUEST).into_response())
135+
}
136+
84137
async fn get_json_handler(req: Request) -> Result<Response, AppError> {
85138
let url = req.uri().path();
86139
let req_id = REQ_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);

0 commit comments

Comments
 (0)