Skip to content

Commit cf2a4fe

Browse files
committed
controllers/krate/publish: Extract read_tarball_bytes() fn
1 parent 9733609 commit cf2a4fe

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 =
@@ -633,6 +608,36 @@ async fn read_json_metadata<R: AsyncRead + Unpin>(
633608
.map_err(|e| bad_request(format_args!("invalid upload request: {e}")))
634609
}
635610

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

0 commit comments

Comments
 (0)