Я пытаюсь внедрить фильтр декодирования в конвейер запросов, используя IHttpAsyncHandler, но обнаруживаю, что свойство Request.Filter игнорируется.
Кто-нибудь успешно использовал Request.Filter вместе с 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) {
// never gets here
int c = _sink.Read(buffer, offset, count);
return c;
}
}
РЕДАКТИРОВАТЬ: я нашел другой хороший способ сделать это, не используя Request.Filter, вставленный ниже.Однако, озадачивает, что Request.Filter просто не работает.К вашему сведению, мой вариант использования заключался в декодировании URL до вызова стороннего 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;
}
}