4

IHttpAsyncHandler を使用して要求パイプラインにデコード フィルターを挿入しようとしていますが、Request.Filter プロパティが無視されていることがわかりました。

IHttpAsyncHandler と一緒に Request.Filter を正常に使用した人はいますか?

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 が機能しないというのは不可解です。参考までに、私の使用例は、サードパーティの RequestHandler を呼び出す前に URL デコードを行うことでした。

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;
    }
} 
4

1 に答える 1

0

手遅れなので、httphandler には変更できないことがたくさんあります。そこに HTTPModule を入れてインターセプトし、それが役立つかどうかを確認できます。家で時間があれば、まだ試していないことに注意してください..

于 2012-03-30T16:06:21.997 に答える