Skip to content

Commit 222d6ae

Browse files
committed
controllers/krate/publish: Extract read_tarball_bytes() fn
1 parent 0ad6666 commit 222d6ae

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

src/controllers/krate/publish.rs

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -146,39 +146,14 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
146146
.check_rate_limit(auth.user().id, rate_limit_action, &mut conn)
147147
.await?;
148148

149-
let tarball_len = reader.read_u32_le().await.map_err(|e| {
150-
if e.kind() == std::io::ErrorKind::UnexpectedEof {
151-
bad_request("invalid tarball length")
152-
} else {
153-
e.into()
154-
}
155-
})?;
156-
let content_length = tarball_len as u64;
157-
158149
let maximums = Maximums::new(
159150
existing_crate.as_ref().and_then(|c| c.max_upload_size),
160151
app.config.max_upload_size,
161152
app.config.max_unpack_size,
162153
);
163154

164-
if content_length > maximums.max_upload_size {
165-
return Err(custom(
166-
StatusCode::PAYLOAD_TOO_LARGE,
167-
format!("max upload size is: {}", maximums.max_upload_size),
168-
));
169-
}
170-
171-
let mut tarball_bytes = vec![0; tarball_len as usize];
172-
reader.read_exact(&mut tarball_bytes).await.map_err(|e| {
173-
if e.kind() == std::io::ErrorKind::UnexpectedEof {
174-
let message = format!("invalid tarball length for remaining payload: {tarball_len}");
175-
bad_request(message)
176-
} else {
177-
e.into()
178-
}
179-
})?;
180-
181-
let tarball_bytes = Bytes::from(tarball_bytes);
155+
let tarball_bytes = read_tarball_bytes(&mut reader, maximums.max_upload_size as u32).await?;
156+
let content_length = tarball_bytes.len() as u64;
182157

183158
let pkg_name = format!("{}-{}", &*metadata.name, &version_string);
184159
let tarball_info =
@@ -629,6 +604,36 @@ async fn read_json_metadata(
629604
.map_err(|e| bad_request(format_args!("invalid upload request: {e}")))
630605
}
631606

607+
async fn read_tarball_bytes(
608+
reader: &mut (impl AsyncReadExt + Unpin),
609+
max_length: u32,
610+
) -> Result<Bytes, BoxedAppError> {
611+
let tarball_len = reader.read_u32_le().await.map_err(|e| {
612+
if e.kind() == std::io::ErrorKind::UnexpectedEof {
613+
bad_request("invalid tarball length")
614+
} else {
615+
e.into()
616+
}
617+
})?;
618+
619+
if tarball_len > max_length {
620+
let message = format!("max upload size is: {}", max_length);
621+
return Err(custom(StatusCode::PAYLOAD_TOO_LARGE, message));
622+
}
623+
624+
let mut tarball_bytes = vec![0; tarball_len as usize];
625+
reader.read_exact(&mut tarball_bytes).await.map_err(|e| {
626+
if e.kind() == std::io::ErrorKind::UnexpectedEof {
627+
let message = format!("invalid tarball length for remaining payload: {tarball_len}");
628+
bad_request(message)
629+
} else {
630+
e.into()
631+
}
632+
})?;
633+
634+
Ok(Bytes::from(tarball_bytes))
635+
}
636+
632637
async fn is_reserved_name(name: &str, conn: &mut AsyncPgConnection) -> QueryResult<bool> {
633638
select(exists(reserved_crate_names::table.filter(
634639
canon_crate_name(reserved_crate_names::name).eq(canon_crate_name(name)),

0 commit comments

Comments
 (0)