mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-06-10 00:02:37 -06:00
Stream asset downloads to avoid OutOfMemoryException on large files
ExportAssetDownloader used HttpClient.GetAsync(url, ct), which defaults to HttpCompletionOption.ResponseContentRead and buffers the entire response body into memory before returning. Downloading a large attachment therefore tried to grow a single in-memory buffer to the full file size and threw OutOfMemoryException (HttpContent.LoadIntoBufferAsync -> GrowAndWrite). Pass HttpCompletionOption.ResponseHeadersRead so the body is streamed straight to disk via CopyToAsync in bounded chunks, matching how DiscordClient already issues its requests.
This commit is contained in:
parent
45629c9d7f
commit
e7a9499601
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -63,8 +64,15 @@ internal partial class ExportAssetDownloader(string workingDirPath, bool reuse)
|
||||||
await Http.ResiliencePipeline.ExecuteAsync(
|
await Http.ResiliencePipeline.ExecuteAsync(
|
||||||
async innerCancellationToken =>
|
async innerCancellationToken =>
|
||||||
{
|
{
|
||||||
// Download the file
|
// Download the file.
|
||||||
using var response = await Http.Client.GetAsync(url, innerCancellationToken);
|
// Use ResponseHeadersRead so the response body is streamed to disk instead of
|
||||||
|
// being fully buffered into memory first, which can cause an OutOfMemoryException
|
||||||
|
// on large attachments.
|
||||||
|
using var response = await Http.Client.GetAsync(
|
||||||
|
url,
|
||||||
|
HttpCompletionOption.ResponseHeadersRead,
|
||||||
|
innerCancellationToken
|
||||||
|
);
|
||||||
await using var output = File.Create(filePath);
|
await using var output = File.Create(filePath);
|
||||||
await response.Content.CopyToAsync(output, innerCancellationToken);
|
await response.Content.CopyToAsync(output, innerCancellationToken);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue