99
1010namespace uhttpsharp . Handlers
1111{
12+ public class CompressionHandler : IHttpRequestHandler
13+ {
14+ private readonly IEnumerable < ICompressor > _compressors ;
15+ private static readonly char [ ] Seperator = new [ ] { ',' } ;
16+ public CompressionHandler ( params ICompressor [ ] compressors )
17+ {
18+ _compressors = compressors ;
19+ }
20+
21+ public async Task Handle ( IHttpContext context , Func < Task > next )
22+ {
23+ await next ( ) ;
24+
25+ if ( context . Response == null )
26+ {
27+ return ;
28+ }
29+
30+ var encodings = context . Request . Headers . GetByName ( "Accept-Encoding" )
31+ . Split ( Seperator , StringSplitOptions . RemoveEmptyEntries ) ;
32+
33+ var compressor =
34+ _compressors . FirstOrDefault ( c => encodings . Contains ( c . Name , StringComparer . InvariantCultureIgnoreCase ) ) ;
35+
36+ if ( compressor == null )
37+ {
38+ return ;
39+ }
40+
41+ context . Response = await compressor . Compress ( context . Response ) . ConfigureAwait ( false ) ;
42+ }
43+ }
44+
45+ public interface ICompressor
46+ {
47+
48+ string Name { get ; }
49+
50+ Task < IHttpResponse > Compress ( IHttpResponse response ) ;
51+
52+ }
53+
54+ public class DeflateCompressor : ICompressor
55+ {
56+ public static readonly ICompressor Default = new DeflateCompressor ( ) ;
57+
58+ public string Name
59+ {
60+ get { return "deflate" ; }
61+ }
62+ public Task < IHttpResponse > Compress ( IHttpResponse response )
63+ {
64+ return CompressedResponse . CreateDeflate ( response ) ;
65+ }
66+ }
67+
68+ public class GZipCompressor : ICompressor
69+ {
70+ public static readonly ICompressor Default = new GZipCompressor ( ) ;
71+
72+ public string Name
73+ {
74+ get { return "gzip" ; }
75+ }
76+ public Task < IHttpResponse > Compress ( IHttpResponse response )
77+ {
78+ return CompressedResponse . CreateGZip ( response ) ;
79+ }
80+ }
81+
1282 public class DeflateHandler : IHttpRequestHandler
1383 {
1484 public async Task Handle ( IHttpContext context , Func < Task > next )
@@ -17,19 +87,19 @@ public async Task Handle(IHttpContext context, Func<Task> next)
1787
1888 if ( context . Response != null )
1989 {
20- context . Response = await DeflateResponse . Create ( context . Response ) . ConfigureAwait ( false ) ;
90+ context . Response = await CompressedResponse . CreateDeflate ( context . Response ) . ConfigureAwait ( false ) ;
2191 }
2292 }
2393 }
2494
25- public class DeflateResponse : IHttpResponse
95+ public class CompressedResponse : IHttpResponse
2696 {
2797 private readonly HttpResponseCode _responseCode ;
2898 private readonly IHttpHeaders _headers ;
2999 private readonly MemoryStream _memoryStream ;
30100 private readonly bool _closeConnection ;
31101
32- public DeflateResponse ( IHttpResponse child , MemoryStream memoryStream )
102+ public CompressedResponse ( IHttpResponse child , MemoryStream memoryStream , string encoding )
33103 {
34104 _memoryStream = memoryStream ;
35105
@@ -41,24 +111,35 @@ public DeflateResponse(IHttpResponse child, MemoryStream memoryStream)
41111 . Concat ( new [ ]
42112 {
43113 new KeyValuePair < string , string > ( "content-length" , memoryStream . Length . ToString ( CultureInfo . InvariantCulture ) ) ,
44- new KeyValuePair < string , string > ( "content-encoding" , "deflate" ) ,
114+ new KeyValuePair < string , string > ( "content-encoding" , encoding ) ,
45115 } )
46116 . ToList ( ) ) ;
47117
48118
49119 }
50120
51- public static async Task < DeflateResponse > Create ( IHttpResponse child )
121+
122+ public static async Task < IHttpResponse > Create ( IHttpResponse child , Func < Stream , Stream > streamFactory )
52123 {
53124 var memoryStream = new MemoryStream ( ) ;
54- using ( var deflateStream = new DeflateStream ( memoryStream , CompressionMode . Compress , true ) )
125+ using ( var deflateStream = streamFactory ( memoryStream ) )
55126 using ( var deflateWriter = new StreamWriter ( deflateStream ) )
56127 {
57128 await child . WriteBody ( deflateWriter ) . ConfigureAwait ( false ) ;
58129 await deflateWriter . FlushAsync ( ) ;
59130 }
60131
61- return new DeflateResponse ( child , memoryStream ) ;
132+ return new CompressedResponse ( child , memoryStream , "deflate" ) ;
133+ }
134+
135+ public static Task < IHttpResponse > CreateDeflate ( IHttpResponse child )
136+ {
137+ return Create ( child , s => new DeflateStream ( s , CompressionMode . Compress , true ) ) ;
138+ }
139+
140+ public static Task < IHttpResponse > CreateGZip ( IHttpResponse child )
141+ {
142+ return Create ( child , s => new GZipStream ( s , CompressionMode . Compress , true ) ) ;
62143 }
63144
64145 public async Task WriteBody ( StreamWriter writer )
0 commit comments