13

gzip でエンコードされたリクエストをサポートするサーバーに、http ポスト リクエストで大量のデータを送信する必要があります。

簡単なことから始める

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 が機能しないのはなぜですか?
  • 送信中に圧縮バッファをメモリにロードせずにオンザフライで圧縮する方法は?

どんな助けでも大歓迎です。

4

1 に答える 1