Replace Text in a Stream: StreamReader and StreamWriter
The problem with the previous methods is that we need to read the entire request into memory and convert it to string before we can do our search and replace. This explains the high memory usage.
A better way would be to work on just a part the request and send it to the response as soon as possible, which should reduce the memory footprint significantly. This is what is called a circular buffer. In that pattern, you read a part of the original stream called a buffer. You do your work in the buffer and send it to the output stream. Only then you read the next part of the input stream, overwriting the buffer. You only keep the buffer in memory and not the whole input stream.