@@ -69,36 +69,7 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
69
69
// .crate tarball file
70
70
71
71
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 ?;
102
73
103
74
Crate :: validate_crate_name ( "crate" , & metadata. name ) . map_err ( bad_request) ?;
104
75
@@ -627,6 +598,37 @@ async fn count_versions_published_today(
627
598
. await
628
599
}
629
600
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
+
630
632
async fn is_reserved_name ( name : & str , conn : & mut AsyncPgConnection ) -> QueryResult < bool > {
631
633
select ( exists ( reserved_crate_names:: table. filter (
632
634
canon_crate_name ( reserved_crate_names:: name) . eq ( canon_crate_name ( name) ) ,
0 commit comments