@@ -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
@@ -627,6 +598,37 @@ async fn count_versions_published_today(
627598 . await
628599}
629600
601+ async fn read_json_metadata (
602+ reader : & mut ( impl AsyncReadExt + Unpin ) ,
603+ max_length : u32 ,
604+ ) -> Result < PublishMetadata , BoxedAppError > {
605+ let json_len = reader. read_u32_le ( ) . await . map_err ( |e| {
606+ if e. kind ( ) == std:: io:: ErrorKind :: UnexpectedEof {
607+ bad_request ( "invalid metadata length" )
608+ } else {
609+ e. into ( )
610+ }
611+ } ) ?;
612+
613+ if json_len > max_length {
614+ let message = "JSON metadata blob too large" ;
615+ return Err ( custom ( StatusCode :: PAYLOAD_TOO_LARGE , message) ) ;
616+ }
617+
618+ let mut json_bytes = vec ! [ 0 ; json_len as usize ] ;
619+ reader. read_exact ( & mut json_bytes) . await . map_err ( |e| {
620+ if e. kind ( ) == std:: io:: ErrorKind :: UnexpectedEof {
621+ let message = format ! ( "invalid metadata length for remaining payload: {json_len}" ) ;
622+ bad_request ( message)
623+ } else {
624+ e. into ( )
625+ }
626+ } ) ?;
627+
628+ serde_json:: from_slice ( & json_bytes)
629+ . map_err ( |e| bad_request ( format_args ! ( "invalid upload request: {e}" ) ) )
630+ }
631+
630632async fn is_reserved_name ( name : & str , conn : & mut AsyncPgConnection ) -> QueryResult < bool > {
631633 select ( exists ( reserved_crate_names:: table. filter (
632634 canon_crate_name ( reserved_crate_names:: name) . eq ( canon_crate_name ( name) ) ,
0 commit comments