c# - DelegatingHandler to decompress incoming requests in WebApi -


in app sending decent size packets client , receiving decent sized response, want implement compression on way , way back.

on way fine because can lean on iis's dynamic compression me, on way finding following issue.

i have delegating handler sits there decompress incoming requests: (most of code based on parts of fabrik.common (https://github.com/benfoster/fabrik.common))

public class decompressionhandler : delegatinghandler {     public collection<icompressor> compressors;      public decompressionhandler()     {         compressors = new collection<icompressor> {new gzipcompressor(), new deflatecompressor()};     }      protected async override task<httpresponsemessage> sendasync(httprequestmessage request, system.threading.cancellationtoken cancellationtoken)     {         if (request.content.headers.contentencoding.isntnullorempty() && request.content != null)         {             var encoding = request.content.headers.contentencoding.first();              var compressor = compressors.firstordefault(c => c.encodingtype.equals(encoding, stringcomparison.invariantcultureignorecase));              if (compressor != null)             {                 request.content = await decompresscontentasync(request.content, compressor).configureawait(true);             }         }          var response = await base.sendasync(request, cancellationtoken).configureawait(true);          return response;     }      private static async task<httpcontent> decompresscontentasync(httpcontent compressedcontent, icompressor compressor)     {         using (compressedcontent)         {             var decompressed = new memorystream();             await compressor.decompress(await compressedcontent.readasstreamasync(), decompressed).configureawait(true);              // set position 0 can read again             decompressed.position = 0;              var newcontent = new streamcontent(decompressed);             // copy content type know how load correct formatter             newcontent.headers.contenttype = compressedcontent.headers.contenttype;             return newcontent;         }     } }  public class deflatecompressor : compressor {     private const string deflateencoding = "deflate";      public override string encodingtype     {         { return deflateencoding; }     }      public override stream createcompressionstream(stream output)     {         return new deflatestream(output, compressionmode.compress, leaveopen: true);     }      public override stream createdecompressionstream(stream input)     {         return new deflatestream(input, compressionmode.decompress, leaveopen: true);     } } public abstract class compressor : icompressor {     public abstract string encodingtype { get; }     public abstract stream createcompressionstream(stream output);     public abstract stream createdecompressionstream(stream input);      public virtual task compress(stream source, stream destination)     {         var compressed = createcompressionstream(destination);          return pump(source, compressed)             .continuewith(task => compressed.dispose());     }      public virtual task decompress(stream source, stream destination)     {         var decompressed = createdecompressionstream(source);          return pump(decompressed, destination)             .continuewith(task => decompressed.dispose());     }      protected virtual task pump(stream input, stream output)     {         return input.copytoasync(output);     } }  public interface icompressor {     string encodingtype { get; }     task compress(stream source, stream destination);     task decompress(stream source, stream destination); }  public class gzipcompressor : compressor {     private const string gzipencoding = "gzip";      public override string encodingtype     {         { return gzipencoding; }     }      public override stream createcompressionstream(stream output)     {         return new gzipstream(output, compressionmode.compress, leaveopen: true);     }      public override stream createdecompressionstream(stream input)     {         return new gzipstream(input, compressionmode.decompress, leaveopen: true);     } } 

the decompression works fine , have request.content populated result decompressed json.

when pass off base.sendasync , hits controller method, model null, whereas before implemented compression working great.

i have read when read content stream coming in once off thing, thought setting request.content decompressed result should let read again?

i resolved this.

it error in httpclient implementation had moved using postasjsonasync postasync compression client side, had not added content-type header specify application/json.

after doing in client, working planned.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -