2011-02-04 1 views
2

私はスタックオーバーフローとGoogleの両方で、私が達成しようとしていることと私が直面している問題について説明しながら、私と一緒に抱いてください。SharePoint HTTPModuleのフィルタを使用してバイナリデータを傍受すると壊れたデータが返される

私は、ブラウザから要求された画像(jpg、gif、png)に基本透かしを追加するSharePoint 2007アプリケーションを開発しています。 '12ハイブ 'の一環として、イメージがドキュメントライブラリやサーバーのファイルシステムに存在するかどうかは関係ありません。 (これはビルドされているソリューションの簡素化であり、私は無関係の詳細であなたを退屈させたくありません)。

SharePointで実行されている可能性のあるサードパーティのソリューションとは関係なく、提供されているイメージで動作する必要があるため、HTTPModuleを作成し、モジュールのフィルタをフックし、そのストリームをウォーターマークされたバージョンのイメージに置き換えます。このためにSharePointのイベント受信者を使用することはできません。また、SharePointの「サーバー側のファイルハンドラー」は、これらの種類のファイルをブラウザーに配信するすべてのシナリオを網羅していません。

フィルタを使用してテキストベースのコンテンツを傍受して変更するのは問題ありませんが、フィルタにバイナリデータが含まれている場合、カスタムフィルタのWriteメソッドは破損したデータを受け取ります。 byte []は、ソースファイルで00が見つかるまで正しいので、(バイナリデータの)エンコードの問題やHTTPModuleフィルタのように聞こえて、バイナリデータが信じられないように思えます。

バイナリファイル(イメージ)がSharePointによってサーバーのファイルシステムから読み取られるとき、それは適切にフィルタを通過するということです。ただし、バイナリファイルをSharePoint Document Libraryから読み取ると、データが破損します。

私は次のテストを実施してきたこれを確認するには、次のサーバのファイルシステムとSharePointドキュメントライブラリの両方から1.3メガバイトのTXTファイルを要求

  1. が正常に動作します。ファイルシステムから読み込むと、大きなチャンクに到着します。ドキュメントライブラリから読み取ると、32KBのサイズのチャンクに届きます。

  2. サーバーのファイルシステムに存在する300KBバイナリイメージの要求は、フィルタによって正常に処理されます。ただし、ドキュメントライブラリから同じファイルを要求すると、破損したデータが返されます。

  3. ドキュメントライブラリから3KBのGIFイメージを要求すると、破損したデータが返されます。最初の10バイトは正常終了した後、データは破損します(バイト10はソースファイルの0です)

  4. カスタムフィルタが有効になっていない場合、要求されたファイルは常にブラウザに正常に返されます。

  5. カスタムフィルタのエントリポイントはWriteメソッドです。このメソッドに渡されたバッファ内のデータは、すでに破損しています。

  6. 複数のHTTPModuleがチェーンされていることを理解します。私はカスタムモジュールをWebのモジュールリストの最初と最後に配置しようとしました。次のように運が良けれ

フィルタをフック用HttpModuleを内の関連するコードのない設定ファイルは、次のとおりです。

void context_BeginRequest(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.Filter = new ResponseFilter(HttpContext.Current.Response.Filter); 
} 

次のようにResponseFilterクラスの実装です。ソースデータを出力ストリームに書き戻す以外は、実際には何もしません。

public class ResponseFilter : Stream 
{ 
    private MemoryStream internalStream = new MemoryStream(); 
    private Stream responseStream; 

    public ResponseFilter(Stream outputStream) 
    { 
     responseStream = outputStream; 
    } 

    public override void Flush() 
    { 
     responseStream.Flush(); 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     internalStream.Write(buffer, offset, count); 
     responseStream.Write(buffer, offset, count); 
    } 

    public override void Close() 
    { 
     responseStream.Close(); 
    } 

    public override bool CanRead 
    { 
     get { return true; } 
    } 

    public override bool CanWrite 
    { 
     get { return true; } 
    } 

    public override bool CanSeek 
    { 
     get { return true; } 
    } 

    public override long Length 
    { 
     get { return internalStream.Length; } 
    } 

    public override long Position 
    { 
     get { return internalStream.Position; } 
     set { internalStream.Position = value; } 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     return internalStream.Read(buffer, offset, count); 
    } 

    public override long Seek(long offset, SeekOrigin direction) 
    { 
     return internalStream.Seek(offset, direction); 
    } 

    public override void SetLength(long length) 
    { 
     internalStream.SetLength(length); 
    } 

} 

このクラスは、はるかに完璧からですが、問題はWriteメソッドは、バッファ内のデータをヒットした瞬間が既に破損していることです。残りのクラスは現時点では問題ありません。

答えて

0

これは古い質問であり、この問題を解決した可能性があります。まだ開いている場合は、キャッシュ後の置換を無効にすると破損の問題が解決されるかどうかをテストすることを検討することもできます。詳細については、ASP.Net Response Filter Clashing with SharePoint 2010 Publishing Site Defaultsを参照してください。それは長い試合だが、テストには時間がかかるかもしれない。