@@ -274,17 +274,38 @@ async def on_chunk(chunk):
274274 print (f"DownloadManager: HTTP error { response .status } " )
275275 raise RuntimeError (f"HTTP { response .status } " )
276276
277- # Figure out total size
277+ # Figure out total size and starting offset (for resume support)
278278 print ("DownloadManager: Response headers:" , response .headers )
279+ resume_offset = 0 # Starting byte offset (0 for new downloads, >0 for resumed)
280+
279281 if total_size is None :
280282 # response.headers is a dict (after parsing) or None/list (before parsing)
281283 try :
282284 if isinstance (response .headers , dict ):
283- content_length = response .headers .get ('Content-Length' )
284- if content_length :
285- total_size = int (content_length )
286- except (AttributeError , TypeError , ValueError ) as e :
287- print (f"DownloadManager: Could not parse Content-Length: { e } " )
285+ # Check for Content-Range first (used when resuming with Range header)
286+ # Format: 'bytes 1323008-3485807/3485808'
287+ # START is the resume offset, TOTAL is the complete file size
288+ content_range = response .headers .get ('Content-Range' )
289+ if content_range :
290+ # Parse total size and starting offset from Content-Range header
291+ # Example: 'bytes 1323008-3485807/3485808' -> offset=1323008, total=3485808
292+ if '/' in content_range and ' ' in content_range :
293+ # Extract the range part: '1323008-3485807'
294+ range_part = content_range .split (' ' )[1 ].split ('/' )[0 ]
295+ # Extract starting offset
296+ resume_offset = int (range_part .split ('-' )[0 ])
297+ # Extract total size
298+ total_size = int (content_range .split ('/' )[- 1 ])
299+ print (f"DownloadManager: Resuming from byte { resume_offset } , total size: { total_size } " )
300+
301+ # Fall back to Content-Length if Content-Range not present
302+ if total_size is None :
303+ content_length = response .headers .get ('Content-Length' )
304+ if content_length :
305+ total_size = int (content_length )
306+ print (f"DownloadManager: Using Content-Length: { total_size } " )
307+ except (AttributeError , TypeError , ValueError , IndexError ) as e :
308+ print (f"DownloadManager: Could not parse Content-Range/Content-Length: { e } " )
288309
289310 if total_size is None :
290311 print (f"DownloadManager: WARNING: Unable to determine total_size, assuming { _DEFAULT_TOTAL_SIZE } bytes" )
@@ -298,7 +319,7 @@ async def on_chunk(chunk):
298319 return False
299320
300321 chunks = []
301- partial_size = 0
322+ partial_size = resume_offset # Start from resume offset for accurate progress
302323 chunk_size = _DEFAULT_CHUNK_SIZE
303324
304325 # Progress tracking with 2-decimal precision
0 commit comments