I am trying to inject a decoding filter into the request pipeline using IHttpAsyncHandler, but I find that the Request.Filter property is ignored.
Has anyone successfully used Request.Filter with IHttpAsyncHandler?
public class DecodeHttpHandler : IHttpAsyncHandler { public void ProcessRequest(HttpContext context) { context.Request.Filter = new DecodeStream(context.Request.Filter); } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { var decodeContext = new DecodeContext(context); var w = new HttpContextWrapper(context); w.Request.Filter = new DecodeStream(w.Request.Filter); return RequestHandler.BeginProcessRequestBase(w, cb, extraData); } public void EndProcessRequest(IAsyncResult result){ RequestHandler.EndProcessRequestBase(result); } public bool IsReusable { get { return true; } } } public class DecodeStream : Stream { ... details ... public override int Read(byte[] buffer, int offset, int count) {
EDIT: I found another good way to do this without using the Request.Filter inserted below. However, it is puzzling that Request.Filter just does not work. FYI, my use case was to decode the URL before calling a third-party RequestHandler.
public class UrlDecodeHttpHandler : IHttpAsyncHandler { public void ProcessRequest(HttpContext context) { throw new NotImplementedException(); } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { var decodeContext = new DecodeContext(context); return RequestHandler.BeginProcessRequestBase(decodeContext, cb, extraData); } public void EndProcessRequest(IAsyncResult result){ RequestHandler.EndProcessRequestBase(result); } public bool IsReusable { get { return false; } } } public class DecodeContext : HttpContextWrapper { private readonly HttpContext _context; public DecodeContext(HttpContext httpContext) : base(httpContext){ _context = httpContext; } public override HttpRequestBase Request { get { return new DecodeRequest(_context.Request); } } } public class DecodeRequest : HttpRequestWrapper { public DecodeRequest(HttpRequest request) : base(request) {} public override Stream InputStream { get { string result; using (var sr = new StreamReader(base.InputStream)) { result = HttpUtility.UrlDecode(sr.ReadToEnd()); } return GenerateStreamFromString(result); } } private static Stream GenerateStreamFromString(string s) { var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.Write(s); writer.Flush(); stream.Position = 0; return stream; } }
dcpar source share