Let's prove how much better the SharePoint Overflow community is as on Stack Overflow there is a big silence when things become difficult, at least for this question.
I'll omit the wall of text, for full details see this question on Stack Overflow. In summary I have created an HTTPModule based Filter to intercept response streams for binary files so I can modify the content. This is all working fine when the file being requested lives on the server's file system, but if the file is stored in a document library then the data passed to the filter is corrupt. Basically it goes wrong after the first 0 in the stream.
Update 1: Example of corrupt data: Source file : "21 EC 34 00 BA D8". Data that arrives in the write method "21 EC 34 BA BF BF BF BF" (Note how the 00 is removed and data becomes incorrect)
Update 2: I can reproduce the problem on other SharePoint 2007 servers, but on SharePoint 2010 everything works fine.
The relevant code in the HTTPModule for hooking up the filter is as follows:
void context_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.Filter = new ResponseFilter(HttpContext.Current.Response.Filter);
}
The implementation of the ResponseFilter Class is as follows. Note that it doesn't actually do anything at the moment other than writing the source data back to the output stream. As the data being passed into the filter is incorrect the resulting output stream is incorrect as well. When the filter is not active, or the file is located outside a Document Library, then it work just fine.
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);
}
}
This class is far from perfect, but the problem is that the moment the Write method is hit the data in the buffer is already corrupt. The rest of the class doesn't matter at the moment.