I'm curious how this code is actually working to be honest. It appears that in the case of an exception and a response body is sent back then you're going to read the error response and write out something else. The issue I see is that you're reading and writing to the response stream. The response stream is what came back from the original request and can't/shouldn't be modified.
While (InlineAssignHelper(bytesRead, responseStream.Read(bytes, 0, bytes.Length))) > 0
responseStream.Write(bytes, 0, bytesRead)
End While
I'm surprised that would work as I assumed the response stream was read only. Even if it did allow writing, you are in a loop to read the response in 32K chunks (approximately) so you're mixing read and write code on the same stream. This isn't going to end well. A stream has only one "position" field. Reading and writing use that. So imagine that you read the first 32K of data from the stream. Then you write out that "encoded" data to the same stream. It'll be after the unencoded version (unless your helper method is doing far more than just reading).
Personally I would recommend you remove this code from here. If you need to transform stream data then you create a new stream class that accepts another stream class as a parameter. Then the stream can transform the data as it is being read (if ever). This is how encryption and compression streams work and can be applied to any stream, anywhere. Imagine you create a custom EncodeStream
class. Your existing code simplifies down to this.
Using responseStream As Stream = new EncodedStream(webExc.Response.GetResponseStream())
context.Response.StatusCode = CInt(TryCast(webExc.Response, System.Net.HttpWebResponse).StatusCode)
responseStream.CopyTo(context.Response.OutputStream)
End Using
The class to wrap a stream isn't hard to write but does require knowledge of your "encoding" rules which you didn't really provide. It is also very important that you properly handle clean up of the base stream. Here's the start of a Stream
wrapper class but I haven't tested it.
Imports System.IO
Public Class EncodedStream
Inherits Stream
Public Sub New(stream As Stream)
InnerStream = stream
End Sub
Public Overrides ReadOnly Property CanRead As Boolean
Get
Return InnerStream.CanRead
End Get
End Property
Public Overrides ReadOnly Property CanSeek As Boolean
Get
Return InnerStream.CanSeek
End Get
End Property
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return InnerStream.CanWrite
End Get
End Property
Public Overrides ReadOnly Property Length As Long
Get
Return InnerStream.Length
End Get
End Property
Public Overrides Property Position As Long
Get
Return InnerStream.Position
End Get
Set
InnerStream.Position = Value
End Set
End Property
Protected Overrides Sub Dispose(disposing As Boolean)
If (disposing) Then
InnerStream.Dispose()
End If
End Sub
Public Overrides Sub Flush()
InnerStream.Flush()
End Sub
Public Overrides Function Read(buffer As Byte(), offset As Integer, count As Integer) As Integer
Return InnerStream.Read(buffer, offset, count)
End Function
Public Overrides Function Seek(offset As Long, origin As SeekOrigin) As Long
Return InnerStream.Seek(offset, origin)
End Function
Public Overrides Sub SetLength(value As Long)
InnerStream.SetLength(value)
End Sub
Public Overrides Sub Write(buffer As Byte(), offset As Integer, count As Integer)
InnerStream.Write(buffer, offset, count)
End Sub
Protected Property InnerStream As Stream
End Class
The important part here is the Read
method. Override it to do your "encoding" based upon whatever rules you need. Looking at your original code I suspect you'll read from the inner stream, buffered, and call your encoding logic that you're currently using a while loop for. You'll need to add some logic to handle the case of the reader not reading an entire buffer at once and whatnot but it shouldn't be too difficult to figure out. You can refer to the source for one of the existing compression or encryption streams to get a better feel for how to do this.