IHttpAsyncHandler и Request.Filter - PullRequest
       38

IHttpAsyncHandler и Request.Filter

4 голосов
/ 06 марта 2012

Я пытаюсь внедрить фильтр декодирования в конвейер запросов, используя 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;
    }
} 

1 Ответ

0 голосов
/ 30 марта 2012

Есть много вещей, которые вы не можете изменить в httphandler, потому что уже слишком поздно.Вы можете попробовать вставить туда HTTPModule для перехвата и посмотреть, поможет ли это.Обратите внимание, что я еще не пробовал, если у меня будет время, я буду ..

...