Мне нужно отправить объемные данные в почтовом запросе http на сервер, поддерживающий закодированные gzip-запросы.
Начиная с простого
public async Task<string> DoPost(HttpContent content)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync("http://myUri", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Я только что добавил предварительное сжатие
public async Task<string> DoPost(HttpContent content, bool compress)
{
if (compress)
content= await CompressAsync(content);
return await DoPost(content);
}
private static async Task<StreamContent> CompressAsync(HttpContent content)
{
MemoryStream ms = new MemoryStream();
using (GZipStream gzipStream = new GZipStream(ms, CompressionMode.Compress, true))
{
await content.CopyToAsync(gzipStream);
await gzipStream.FlushAsync();
}
ms.Position = 0;
StreamContent compressedStreamContent = new StreamContent(ms);
compressedStreamContent.Headers.ContentType = content.Headers.ContentType;
compressedStreamContent.Headers.Add("Content-Encoding", "gzip");
return compressedStreamContent;
}
Он работает отлично, но сжатые данные полностью загружаются в память перед отправкой запроса. Я хотел бы иметь возможность сжимать данные на лету во время отправки в потоковом режиме.
Для этого я пробовал следующий код:
private static async Task<HttpContent> CompressAsync2(HttpContent content)
{
PushStreamContent pushStreamContent = new PushStreamContent(async (stream, content2, transport) =>
{
using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, true))
{
try
{
await content.CopyToAsync(gzipStream);
await gzipStream.FlushAsync();
}
catch (Exception exception)
{
throw;
}
}
});
pushStreamContent.Headers.ContentType = content.Headers.ContentType;
pushStreamContent.Headers.Add("Content-Encoding", "gzip");
return pushStreamContent;
}
но он никогда не выходит за пределы CopyToAsync(gzipStream). FlushAsync никогда не выполняется, и исключение не выдается, и Fiddler не видит никаких сообщений.
Мои вопросы:
- Почему CompressAsync2 не работает?
- Как сжимать на лету при отправке и без загрузки сжатого буфера в память?
Любая помощь будет принята с благодарностью.
PushStreamContent
(в настоящее время) не поддерживаетasync
лямбда-выражений. - person Stephen Cleary   schedule 21.05.2013PushStreamContent
и измените его для поддержкиasync
лямбда-выражений. Это было в моем списке дел в течение нескольких месяцев, просто не было времени на это. - person Stephen Cleary   schedule 21.05.2013