Skip to content

Commit d064636

Browse files
DownloadManager: fix partial download progress reports
Use Content-Range in case of partial downloads.
1 parent 51a5248 commit d064636

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

internal_filesystem/lib/mpos/net/download_manager.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)