Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace XXX.XXX.XXX.XXX.XXX
- {
- public class HttpGZipClientHandler : System.Net.Http.HttpClientHandler
- {
- long time = 0;
- private long _downloadedBytesFromServer;
- private long _downloadedProcessedBytes;
- private long _intendedUploadedBytesToServer;
- private long _uploadedBytesToServer;
- private long _additionalTimeOverhead = 0;
- public override bool SupportsAutomaticDecompression { get { return true; } }
- public long DownloadedBytesFromServer { get { return _downloadedBytesFromServer; } }
- public long DownloadedProcessedBytes { get { return _downloadedProcessedBytes; } }
- public long IntendedUploadedBytesToServer { get { return _intendedUploadedBytesToServer; } }
- public long UploadedBytesToServer { get { return _uploadedBytesToServer; } }
- public long AdditionalTimeOverhead { get { return _additionalTimeOverhead; } }
- public void ResetStatistics()
- {
- _downloadedBytesFromServer = 0;
- _downloadedProcessedBytes = 0;
- _intendedUploadedBytesToServer = 0;
- _uploadedBytesToServer = 0;
- _additionalTimeOverhead = 0;
- }
- protected override async Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
- {
- //Save content headers before compressing
- System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>> savedContentHeaders = new Dictionary<string, IEnumerable<string>>();
- foreach (System.Collections.Generic.KeyValuePair<string, System.Collections.Generic.IEnumerable<string>> keyValue in request.Content.Headers)
- {
- savedContentHeaders.Add(keyValue.Key, keyValue.Value);
- }
- //Compress request content
- System.Diagnostics.Stopwatch sp1 = new System.Diagnostics.Stopwatch();
- sp1.Start();
- _intendedUploadedBytesToServer += request.Content.Headers.ContentLength.HasValue ? request.Content.Headers.ContentLength.Value : 0;
- await request.Content.LoadIntoBufferAsync().ConfigureAwait(false);
- request.Content = new HttpGZipContent(await request.Content.ReadAsByteArrayAsync().ConfigureAwait(false), System.IO.Compression.CompressionMode.Compress);
- byte[] uploadedBytes = await request.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
- _uploadedBytesToServer += uploadedBytes.Length;
- sp1.Stop();
- _additionalTimeOverhead += sp1.ElapsedMilliseconds;
- //Set headers
- foreach (System.Collections.Generic.KeyValuePair<string, System.Collections.Generic.IEnumerable<string>> keyValue in savedContentHeaders)
- {
- request.Content.Headers.Add(keyValue.Key, keyValue.Value);
- }
- request.Headers.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
- request.Content.Headers.Add("Content-Encoding", "gzip");
- //Execute request
- System.Net.Http.HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
- _downloadedBytesFromServer += response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : 0;
- //Decompress response content
- if (response.Content.Headers.ContentEncoding.Contains("gzip"))
- {
- System.Diagnostics.Stopwatch sp2 = new System.Diagnostics.Stopwatch();
- sp2.Start();
- await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
- response.Content = new HttpGZipContent(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false), System.IO.Compression.CompressionMode.Decompress);
- byte[] processedBytes = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
- _downloadedProcessedBytes += processedBytes.Length;
- sp2.Stop();
- _additionalTimeOverhead += sp2.ElapsedMilliseconds;
- }
- else
- _downloadedProcessedBytes += response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : 0;
- return response;
- }
- }
- internal sealed class HttpGZipContent : System.Net.Http.HttpContent
- {
- private readonly byte[] _content;
- private readonly System.IO.Compression.CompressionMode _compressionMode;
- public HttpGZipContent(byte[] content, System.IO.Compression.CompressionMode compressionMode)
- {
- _compressionMode = compressionMode;
- _content = content;
- }
- protected override async System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context)
- {
- if (_compressionMode == System.IO.Compression.CompressionMode.Compress)
- {
- using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(_content.Length))
- {
- using (System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(memoryStream, System.IO.Compression.CompressionMode.Compress))
- {
- zipStream.Write(_content, 0, _content.Length);
- zipStream.Flush();
- }
- byte[] compressed = memoryStream.ToArray();
- System.IO.MemoryStream copyStream = new System.IO.MemoryStream(compressed);
- await copyStream.CopyToAsync(stream).ConfigureAwait(false);
- }
- }
- else
- {
- using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(_content, 0, _content.Length))
- {
- using (System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(memoryStream, System.IO.Compression.CompressionMode.Decompress))
- {
- await zipStream.CopyToAsync(stream).ConfigureAwait(false);
- }
- }
- }
- }
- protected override bool TryComputeLength(out long length)
- {
- length = _content.Length;
- return true;
- }
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- }
- }
- }
Add Comment
Please, Sign In to add comment