How can I insert a string into the response stream anywhere?

There may be an easy way to do this, but I do not see it ...

I created a simple Http module that starts a timer in PreRequestHandler and stops the timer on PostRequestHandler to calculate page load time.

Then I create a simple html and write my results in Response.Write. Since I do this in PostRequestHandler, it adds my results after the tag </html>. This is good for testing, but I need in a scenario where the page should be checked.

I cannot figure out how I can manipulate the Response object to insert my results before the tag </body>. Response.Write and Response.Output.Write do not have such flexibility, and I could not see how to work with Response as a string. Am I missing something?

+5
source share
1 answer

To do this, you will need to implement your own stream object and use it as a filter for your response.

For isntance:

public class TimerStream : Stream
{
    private Stream inner { get; set; }
    private StringBuilder   responseHtml;

    public TimerStream(Stream inputStream) { 
        inner = inputStream; 
        responseHtml = new StringBuilder();
        // Setup your timer
    }

    /* Filter overrides should pass through to inner, all but Write */
    public override void Write(byte[] buffer, int offset, int count)
    {
        string bufferedHtml = System.Text.UTF8Encoding.UTF8.GetString (buffer, offset, count);
        Regex endTag = new Regex ("</html>", RegexOptions.IgnoreCase);

        if (!endTag.IsMatch (bufferedHtml))
        {
            responseHtml.Append(bufferedHtml);
        }
        else
        {
            // insert timer html into buffer, then...
            responseHtml.Append (bufferedHtml);
            byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes (responseHtml.ToString ());            
            inner.Write (data, 0, data.Length);            
        }
    }
}

Then in your HttpModule you add this to your BeginRequest:

// Change the Stream filter
HttpResponse response = context.Response;
response.Filter = new TimerStream(context.Response.Filter);
+8
source

All Articles