This repository has been archived by the owner on Sep 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplified usage, and added support for setting a minimum content siz…
…e for compressing.
- Loading branch information
Showing
20 changed files
with
848 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
src/Microsoft.AspNet.WebApi.MessageHandlers.Compression.jmconfig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?xml version="1.0" encoding="utf-8"?><Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><DontShowAgainInSolution>false</DontShowAgainInSolution></Configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
src/Microsoft.AspNet.WebApi.MessageHandlers.Compression/ClientCompressionHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
namespace Microsoft.AspNet.WebApi.MessageHandlers.Compression | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
using Microsoft.AspNet.WebApi.MessageHandlers.Compression.Interfaces; | ||
using Microsoft.AspNet.WebApi.MessageHandlers.Compression.Models; | ||
|
||
/// <summary> | ||
/// Message handler for handling gzip/deflate requests/responses on a <see cref="HttpClient"/>. | ||
/// </summary> | ||
public class ClientCompressionHandler : DelegatingHandler | ||
{ | ||
/// <summary> | ||
/// The content size threshold before compressing. | ||
/// </summary> | ||
private readonly int contentSizeThreshold; | ||
|
||
/// <summary> | ||
/// The HTTP content operations | ||
/// </summary> | ||
private readonly HttpContentOperations httpContentOperations; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ClientCompressionHandler" /> class. | ||
/// </summary> | ||
/// <param name="compressors">The compressors.</param> | ||
public ClientCompressionHandler(params ICompressor[] compressors) | ||
{ | ||
this.Compressors = compressors; | ||
this.httpContentOperations = new HttpContentOperations(); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ClientCompressionHandler" /> class. | ||
/// </summary> | ||
/// <param name="contentSizeThreshold">The content size threshold before compressing.</param> | ||
/// <param name="compressors">The compressors.</param> | ||
public ClientCompressionHandler(int contentSizeThreshold, params ICompressor[] compressors) | ||
: this(compressors) | ||
{ | ||
this.contentSizeThreshold = contentSizeThreshold; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ClientCompressionHandler" /> class. | ||
/// </summary> | ||
/// <param name="innerHandler">The inner handler.</param> | ||
/// <param name="compressors">The compressors.</param> | ||
public ClientCompressionHandler(HttpMessageHandler innerHandler, params ICompressor[] compressors) | ||
: this(compressors) | ||
{ | ||
this.InnerHandler = innerHandler; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ClientCompressionHandler" /> class. | ||
/// </summary> | ||
/// <param name="innerHandler">The inner handler.</param> | ||
/// <param name="contentSizeThreshold">The content size threshold before compressing.</param> | ||
/// <param name="compressors">The compressors.</param> | ||
public ClientCompressionHandler(HttpMessageHandler innerHandler, int contentSizeThreshold, params ICompressor[] compressors) | ||
: this(contentSizeThreshold, compressors) | ||
{ | ||
this.InnerHandler = innerHandler; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the compressors. | ||
/// </summary> | ||
/// <value>The compressors.</value> | ||
public ICollection<ICompressor> Compressors { get; private set; } | ||
|
||
/// <summary> | ||
/// send as an asynchronous operation. | ||
/// </summary> | ||
/// <param name="request">The HTTP request message to send to the server.</param> | ||
/// <param name="cancellationToken">A cancellation token to cancel operation.</param> | ||
/// <returns>Returns <see cref="T:System.Threading.Tasks.Task`1" />. The task object representing the asynchronous operation.</returns> | ||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||
{ | ||
// Compress uncompressed requests from the client to the server | ||
if (request.Content != null && request.Headers.AcceptEncoding.Any()) | ||
{ | ||
await this.CompressRequest(request); | ||
} | ||
|
||
var response = await base.SendAsync(request, cancellationToken); | ||
|
||
// Decompress compressed responses to the client from the server | ||
if (response.Content != null && response.Content.Headers.ContentEncoding.Any()) | ||
{ | ||
await this.DecompressResponse(response); | ||
} | ||
|
||
return response; | ||
} | ||
|
||
/// <summary> | ||
/// Compresses the content. | ||
/// </summary> | ||
/// <param name="request">The request.</param> | ||
/// <returns>An async void.</returns> | ||
private async Task CompressRequest(HttpRequestMessage request) | ||
{ | ||
// As per RFC2616.14.3: | ||
// Ignores encodings with quality == 0 | ||
// If multiple content-codings are acceptable, then the acceptable content-coding with the highest non-zero qvalue is preferred. | ||
var compressor = (from encoding in request.Headers.AcceptEncoding | ||
let quality = encoding.Quality ?? 1.0 | ||
where quality > 0 | ||
join c in this.Compressors on encoding.Value.ToLowerInvariant() equals | ||
c.EncodingType.ToLowerInvariant() | ||
orderby quality descending | ||
select c).FirstOrDefault(); | ||
|
||
if (compressor != null) | ||
{ | ||
// Only compress response if size is larger than threshold (if set) | ||
if (this.contentSizeThreshold == 0) | ||
{ | ||
request.Content = new CompressedContent(request.Content, compressor); | ||
} | ||
else if (this.contentSizeThreshold > 0 && request.Content.Headers.ContentLength >= this.contentSizeThreshold) | ||
{ | ||
request.Content = new CompressedContent(request.Content, compressor); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Decompresses the response. | ||
/// </summary> | ||
/// <param name="response">The response.</param> | ||
/// <returns>An async void.</returns> | ||
private async Task DecompressResponse(HttpResponseMessage response) | ||
{ | ||
var encoding = response.Content.Headers.ContentEncoding.FirstOrDefault(); | ||
|
||
if (encoding != null) | ||
{ | ||
var compressor = this.Compressors.FirstOrDefault(c => c.EncodingType.Equals(encoding, StringComparison.OrdinalIgnoreCase)); | ||
|
||
if (compressor != null) | ||
{ | ||
response.Content = await this.httpContentOperations.DecompressContent(response.Content, compressor); | ||
} | ||
} | ||
} | ||
} | ||
} |
77 changes: 0 additions & 77 deletions
77
src/Microsoft.AspNet.WebApi.MessageHandlers.Compression/CompressionHandler.cs
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.