File tree Expand file tree Collapse file tree 1 file changed +22
-2
lines changed
Expand file tree Collapse file tree 1 file changed +22
-2
lines changed Original file line number Diff line number Diff line change @@ -166,8 +166,28 @@ fn download_file(url: &str, dest: &Path) -> Result<()> {
166166
167167 let total_size = content_length. unwrap_or ( 0 ) ;
168168
169- // Create temp file for atomic download (same directory for atomic rename)
170- let temp_path = dest. with_extension ( "part" ) ;
169+ // Create unique temp file for atomic download to prevent race conditions
170+ // Format: <filename>.part.<pid>.<timestamp_nanos>
171+ let unique_suffix = format ! (
172+ ".{}.{}" ,
173+ std:: process:: id( ) ,
174+ std:: time:: SystemTime :: now( )
175+ . duration_since( std:: time:: UNIX_EPOCH )
176+ . unwrap_or_default( )
177+ . subsec_nanos( )
178+ ) ;
179+ let mut temp_path = dest
180+ . file_name ( )
181+ . map_or_else ( || PathBuf :: from ( "download" ) , PathBuf :: from)
182+ . into_os_string ( ) ;
183+ temp_path. push ( ".part" ) ;
184+ temp_path. push ( unique_suffix) ;
185+
186+ // Create temp path in the same directory as dest to ensure atomic rename works
187+ let temp_path = dest
188+ . parent ( )
189+ . unwrap_or_else ( || Path :: new ( "." ) )
190+ . join ( temp_path) ;
171191
172192 // Clean up any existing partial download
173193 let _ = fs:: remove_file ( & temp_path) ;
You canāt perform that action at this time.
0 commit comments