Skip to content

Commit 9733609

Browse files
committed
controllers/krate/publish: Extract read_json_metadata() fn
1 parent 757ae6d commit 9733609

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

src/controllers/krate/publish.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use http::request::Parts;
2121
use http::StatusCode;
2222
use sha2::{Digest, Sha256};
2323
use std::collections::HashMap;
24-
use tokio::io::AsyncReadExt;
24+
use tokio::io::{AsyncRead, AsyncReadExt};
2525
use tokio_util::io::StreamReader;
2626
use url::Url;
2727

@@ -69,36 +69,7 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
6969
// .crate tarball file
7070

7171
const MAX_JSON_LENGTH: u32 = 1024 * 1024; // 1 MB
72-
73-
let json_len = reader.read_u32_le().await.map_err(|e| {
74-
if e.kind() == std::io::ErrorKind::UnexpectedEof {
75-
bad_request("invalid metadata length")
76-
} else {
77-
e.into()
78-
}
79-
})?;
80-
81-
if json_len > MAX_JSON_LENGTH {
82-
return Err(custom(
83-
StatusCode::PAYLOAD_TOO_LARGE,
84-
"JSON metadata blob too large",
85-
));
86-
}
87-
88-
let mut json_bytes = vec![0; json_len as usize];
89-
reader.read_exact(&mut json_bytes).await.map_err(|e| {
90-
if e.kind() == std::io::ErrorKind::UnexpectedEof {
91-
let message = format!("invalid metadata length for remaining payload: {json_len}");
92-
bad_request(message)
93-
} else {
94-
e.into()
95-
}
96-
})?;
97-
98-
let metadata: PublishMetadata = serde_json::from_slice(&json_bytes)
99-
.map_err(|e| bad_request(format_args!("invalid upload request: {e}")))?;
100-
101-
drop(json_bytes);
72+
let metadata = read_json_metadata(&mut reader, MAX_JSON_LENGTH).await?;
10273

10374
Crate::validate_crate_name("crate", &metadata.name).map_err(bad_request)?;
10475

@@ -631,6 +602,37 @@ async fn count_versions_published_today(
631602
.await
632603
}
633604

605+
async fn read_json_metadata<R: AsyncRead + Unpin>(
606+
reader: &mut R,
607+
max_length: u32,
608+
) -> Result<PublishMetadata, BoxedAppError> {
609+
let json_len = reader.read_u32_le().await.map_err(|e| {
610+
if e.kind() == std::io::ErrorKind::UnexpectedEof {
611+
bad_request("invalid metadata length")
612+
} else {
613+
e.into()
614+
}
615+
})?;
616+
617+
if json_len > max_length {
618+
let message = "JSON metadata blob too large";
619+
return Err(custom(StatusCode::PAYLOAD_TOO_LARGE, message));
620+
}
621+
622+
let mut json_bytes = vec![0; json_len as usize];
623+
reader.read_exact(&mut json_bytes).await.map_err(|e| {
624+
if e.kind() == std::io::ErrorKind::UnexpectedEof {
625+
let message = format!("invalid metadata length for remaining payload: {json_len}");
626+
bad_request(message)
627+
} else {
628+
e.into()
629+
}
630+
})?;
631+
632+
serde_json::from_slice(&json_bytes)
633+
.map_err(|e| bad_request(format_args!("invalid upload request: {e}")))
634+
}
635+
634636
async fn is_reserved_name(name: &str, conn: &mut AsyncPgConnection) -> QueryResult<bool> {
635637
select(exists(reserved_crate_names::table.filter(
636638
canon_crate_name(reserved_crate_names::name).eq(canon_crate_name(name)),

0 commit comments

Comments
 (0)