Using Client Technologies on the Server

Whether a type of technology belongs on the front end or the back end is generally considered to be a clear choice: e.g., HTML on the client, SQL on the server; CSS on the front end, C++ on the back. In contrast to some of these patterns, however, we’ve been finding some useful applications of client-side technology being run from the server.

Campaign Thumbnails

For the last year or so, we’ve been displaying small image previews of customer email campaigns in detail and list pages, generating these on demand as the campaigns change.  This has provided context for users, allowing them to find specific campaigns more easily.

Email Campaign Preview

To build these thumbnail images, we’re using a set of servers that are running “headless” browsers: the code feeds the HTML behind the campaign into a browser instance and has it do a “screen shot,” returning the resulting image. As with any server-side usage of client technology, there are some important considerations that we needed to address.

Performance

Rendering a web page can be an expensive operation. In addition to the base cost of parsing and evaluating the HTML, the browser needs to download all of the associated images and other static assets from their various sources. This can easily take upwards of three seconds or more, which, of course, is much too long for a synchronous HTTP request.

We used a client-side polling approach to handle this generation delay. When a thumbnail image is requested and has not yet been generated, a request is placed on a queue and the call returns immediately with a status code 404 (you may see these in the browser debug console – they’re harmless). JavaScript code then calls back to the server periodically asking for the status of this generation process, displaying the image when it is available.  Since the generation process is so costly, we cache the images once they’ve been generated in one of our Cassandra clusters. We also arrange for these images to be cached in the user’s browser “forever” (actually a year). To enable this, we encode the campaign modification time in the image URL. Any particular image can, therefore, be treated as an immutable resource, and the browser can hold onto it unconditionally.

Some folks like to use elastic hosting solutions for this sort of scenario (e.g., Rackspace or Amazon EC2).  Our usage patterns were predictable enough that we could use traditional pre-allocated servers, but not all use cases are this friendly to the DevOps team.

Security

If you’re running some user-supplied HTML through a server-resident browser, you’ll need to be careful to not open vectors for bad guys to attack you (or others.)  Some of the steps that we take to keep our server-side browsing safe include:

  • Keeping browser versions up-to-date
  • Watching out for injection issues (e.g., validate, encode, and never pass a user-entered URL to code that might use a shell)
  • “Walling off” servers via network partitioning so that the browsers cannot “reach back” into the larger corporate network
  • Preventing outgoing requests from the headless browser using methods other than GET – this can keep a piece of HTML, for example, from doing some webspam operation, like posting ad-laden comments to a discussion page

Reliability

As with any piece of software, server-resident browsers will fail from time to time; using this software in a way it was not originally intended ups the chances that something won’t work. We’ve designed our headless browser integrations to be tolerant of failures without disrupting the user experience. We’ll display a default icon in place of the real thumbnail if the generation process doesn’t produce a good result – or even if the whole thumbnail generation system were to be temporarily unavailable, for that matter – and we log the heck out of the generation process so we can spot problematic patterns.

Future Uses

We have a number of additional projects in the work that exploit client technologies on the server side. The common thread of these is analyzing customer content to allow us to provide guidance and customized assets. Watch this space for more details on this and other cool projects here at Constant Contact.

Have a comment? We’d love to hear it!

Leave a Comment