@@ -146,39 +146,14 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
146
146
. check_rate_limit ( auth. user ( ) . id , rate_limit_action, & mut conn)
147
147
. await ?;
148
148
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
-
158
149
let maximums = Maximums :: new (
159
150
existing_crate. as_ref ( ) . and_then ( |c| c. max_upload_size ) ,
160
151
app. config . max_upload_size ,
161
152
app. config . max_unpack_size ,
162
153
) ;
163
154
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 ;
182
157
183
158
let pkg_name = format ! ( "{}-{}" , & * metadata. name, & version_string) ;
184
159
let tarball_info =
@@ -629,6 +604,36 @@ async fn read_json_metadata(
629
604
. map_err ( |e| bad_request ( format_args ! ( "invalid upload request: {e}" ) ) )
630
605
}
631
606
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
+
632
637
async fn is_reserved_name ( name : & str , conn : & mut AsyncPgConnection ) -> QueryResult < bool > {
633
638
select ( exists ( reserved_crate_names:: table. filter (
634
639
canon_crate_name ( reserved_crate_names:: name) . eq ( canon_crate_name ( name) ) ,
0 commit comments