Automatically appending content to served HTML - Apache and IIS

Let's say you want to append content to HTML pages you're serving - like analytics tracking code. If you're like me you're serving at least some static HTML pages and not relying on PHP or other insanity. More specifically, here are the configurations I care about:

  • "cloud hosted" apache2 server, purely static content served out of good old public_html
  • "cloud hosted" IIS server with a .NET-based application

apache2

This is fairly simple, but involves writing a CGI script like it's 1995.
  1. Create public_html/cgi-bin as a directory
  2. Create a file public_html/cgi-bin/footer with this as the contents:
#!/usr/bin/env bash

echo "Content-Type: text/html"
echo ""
cat "$PATH_TRANSLATED"
cat <<EOF
... content you want to append goes here ...
EOF

  1. Mark the file executable, e.g. chmod a+x public_html/cgi-bin/footer
  2. If it doesn't already exist, create a new file public_html/.htaccess
  3. Add the following to public_html/.htaccess
# Append footer to all HTML pages
Action add-ga /cgi-bin/footer
AddHandler add-ga .html

The footer should now be appended to all files with .html extensions served up, regardless of the URL used to access them (e.g. index.html accessed w/o a filename, etc)

IIS

IIS is a bit trickier. 

If you read the docs there are Web config options that seem like they should do the trick with something like: <staticContent enableDocFooter="true" isDocFooterFileName="true" defaultDocFooter="footer.html">. THIS WILL NOT DO WHAT YOU WANT. The isDocFooterFilename attribute is by default "locked" by application config. And even if you use an inline string in defaultDocFooter it is is appended to all static content, not just HTML. So raw text files, XML files, etc would get served with it. Bummer.

Instead, drop this bit of C# into your application:


using System.Configuration;
using System.Net.Mime;

namespace MyNamespace
{
  public class PageFooterModule : IHttpModule
  {
    public String ModuleName { get { return "PageFooterModule"; } }

    public void Init(HttpApplication application)
    {
      string footer = ConfigurationManager.AppSettings["PageFooter"];
      if (string.IsNullOrWhiteSpace(footer))
        return;

      application.EndRequest += (Object source, EventArgs e) => {
        HttpContext context = application.Context;
        if (context.Response.ContentType == MediaTypeNames.Text.Html)
          context.Response.Write(footer);
      };
    }

    public void Dispose() { }
  }
}

And then merge this into your Web.config:

<configuration>
  <system.webServer>
    <modules>
      <add name="PageFooterModule" 
           type="MyNameSpace.PageFooterModule" />
    </modules>
  </system.webServer>
  <appSettings>
    <add key="PageFooter" value="your footer here..." />
  </appSettings>
</configuration>

Note that the footer will need to be escaped for XML, e.g. if your footer is a <script> tag it would be value="&lt;script&gt; ... &lt;/script&gt;"


Comments

  1. https://tvskybox.com
    7500 iptv channels only 5 euro / 5 usd !

    ReplyDelete

Post a Comment