Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4bd6855

Browse files
committed
fix: fix downloading different URLs to same destination
1 parent8f60b4d commit4bd6855

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

‎Tests.Vpn.Service/DownloaderTest.cs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,34 @@ public async Task Download(CancellationToken ct)
284284
Assert.That(awaitFile.ReadAllTextAsync(destPath,ct),Is.EqualTo("test"));
285285
}
286286

287+
[Test(Description="Perform 2 downloads with the same destination")]
288+
[CancelAfter(30_000)]
289+
publicasyncTaskDownloadSameDest(CancellationTokenct)
290+
{
291+
usingvarhttpServer=EchoServer();
292+
varurl0=newUri(httpServer.BaseUrl+"/test0");
293+
varurl1=newUri(httpServer.BaseUrl+"/test1");
294+
vardestPath=Path.Combine(_tempDir,"test");
295+
296+
varmanager=newDownloader(NullLogger<Downloader>.Instance);
297+
varstartTask0=manager.StartDownloadAsync(newHttpRequestMessage(HttpMethod.Get,url0),destPath,
298+
NullDownloadValidator.Instance,ct);
299+
varstartTask1=manager.StartDownloadAsync(newHttpRequestMessage(HttpMethod.Get,url1),destPath,
300+
NullDownloadValidator.Instance,ct);
301+
vardlTask0=awaitstartTask0;
302+
awaitdlTask0.Task;
303+
Assert.That(dlTask0.TotalBytes,Is.EqualTo(5));
304+
Assert.That(dlTask0.BytesRead,Is.EqualTo(5));
305+
Assert.That(dlTask0.Progress,Is.EqualTo(1));
306+
Assert.That(dlTask0.IsCompleted,Is.True);
307+
vardlTask1=awaitstartTask1;
308+
awaitdlTask1.Task;
309+
Assert.That(dlTask1.TotalBytes,Is.EqualTo(5));
310+
Assert.That(dlTask1.BytesRead,Is.EqualTo(5));
311+
Assert.That(dlTask1.Progress,Is.EqualTo(1));
312+
Assert.That(dlTask1.IsCompleted,Is.True);
313+
}
314+
287315
[Test(Description="Download with custom headers")]
288316
[CancelAfter(30_000)]
289317
publicasyncTaskWithHeaders(CancellationTokenct)
@@ -395,9 +423,9 @@ public void CancelledOuter(CancellationToken ct)
395423
varmanager=newDownloader(NullLogger<Downloader>.Instance);
396424
// The "outer" Task should fail.
397425
varsmallerCt=newCancellationTokenSource(TimeSpan.FromSeconds(1)).Token;
398-
Assert.ThrowsAsync<TaskCanceledException>(
399-
async()=>awaitmanager.StartDownloadAsync(newHttpRequestMessage(HttpMethod.Get,url),destPath,
400-
NullDownloadValidator.Instance,smallerCt));
426+
Assert.ThrowsAsync<TaskCanceledException>(async()=>awaitmanager.StartDownloadAsync(
427+
newHttpRequestMessage(HttpMethod.Get,url),destPath,
428+
NullDownloadValidator.Instance,smallerCt));
401429
}
402430

403431
[Test(Description="Timeout on response body")]

‎Vpn.Service/Downloader.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@ public async Task<DownloadTask> StartDownloadAsync(HttpRequestMessage req, strin
288288
{
289289
vartask=_downloads.GetOrAdd(destinationPath,
290290
_=>newDownloadTask(_logger,req,destinationPath,validator));
291-
awaittask.EnsureStartedAsync(ct);
291+
// EnsureStarted is a no-op if we didn't create a new DownloadTask.
292+
// So, we will only remove the destination once for each time we start a new task.
293+
task.EnsureStarted(tsk=>_downloads.TryRemove(destinationPath,out_),ct);
292294

293295
// If the existing (or new) task is for the same URL, return it.
294296
if(task.Request.RequestUri==req.RequestUri)
@@ -357,21 +359,19 @@ internal DownloadTask(ILogger logger, HttpRequestMessage req, string destination
357359
".download-"+Path.GetRandomFileName());
358360
}
359361

360-
internalasyncTask<Task>EnsureStartedAsync(CancellationTokenct=default)
362+
internalvoidEnsureStarted(Action<Task>continuation,CancellationTokenct=default)
361363
{
362-
usingvar_=await_semaphore.LockAsync(ct);
364+
usingvar_=_semaphore.Lock();
363365
if(Task==null!)
364-
Task=awaitStartDownloadAsync(ct);
365-
366-
returnTask;
366+
Task=Start(ct).ContinueWith(continuation,CancellationToken.None);
367367
}
368368

369369
/// <summary>
370370
/// Starts downloading the file. The request will be performed in this task, but once started, the task will complete
371371
/// and the download will continue in the background. The provided CancellationToken can be used to cancel the
372372
/// download.
373373
/// </summary>
374-
privateasyncTask<Task>StartDownloadAsync(CancellationTokenct=default)
374+
privateasyncTaskStart(CancellationTokenct=default)
375375
{
376376
Directory.CreateDirectory(_destinationDirectory);
377377

@@ -398,8 +398,7 @@ private async Task<Task> StartDownloadAsync(CancellationToken ct = default)
398398
thrownewException("Existing file failed validation after 304 Not Modified",e);
399399
}
400400

401-
Task=Task.CompletedTask;
402-
returnTask;
401+
return;
403402
}
404403

405404
if(res.StatusCode!=HttpStatusCode.OK)
@@ -432,11 +431,11 @@ private async Task<Task> StartDownloadAsync(CancellationToken ct = default)
432431
throw;
433432
}
434433

435-
Task=DownloadAsync(res,tempFile,ct);
436-
returnTask;
434+
awaitDownload(res,tempFile,ct);
435+
return;
437436
}
438437

439-
privateasyncTaskDownloadAsync(HttpResponseMessageres,FileStreamtempFile,CancellationTokenct)
438+
privateasyncTaskDownload(HttpResponseMessageres,FileStreamtempFile,CancellationTokenct)
440439
{
441440
try
442441
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp