0

I've got a CDN set up for an old archival site (as subdomain) that has no CMS, just a bunch of .html, .php, and media (mainly images, Flash, and css sheets).

I figure I have at least three options:

  1. Create .htaccess rules to reroute appropriate local URLs to CDN ones. Advantage: easy. Disadvantage: the extra lookup may defeat the purpose of the CDN.
  2. Use regex to alter every local URL to <? echo maybe_get_CDN_url("..."); ?> and write a function that determines whether to return the local or CDN version. Advantage: centralizes CDN url in one file in case we ever switch providers. Disadvantage: smells suspiciously of over-editing (also consider the include statement required in every file, plus running all .html files as .php). Luckily, since this is an archival site whose content won't be edited further, the inconvenience of creating new links with this approach is irrelevant.
  3. Use regex to alter every local URL to a local or CDN one as appropriate. Advantage: leaves the HTML in a straightforward state. Disadvantage: must be repeated if/when the CDN provider changes. (This could be resolved by using a CNAME, of course, but the Cheap as Freeā„¢ SSL and CDN solutions currently in place won't allow flexible enough certificates to work with this. Retort: why don't we remove SSL on this domain since security isn't an issue. Re-retort: if we do that Chrome will start marking this subdomain as insecure, and we won't benefit from HTTP/2.)

So, my question is... which is the least boneheaded of these solutions? :D

Or do any others come to mind?

Community
  • 1
  • 1
Luke Sawczak
  • 239
  • 4
  • 13

1 Answers1

0

In the end, I went with option 2. It seemed to me to essentially emulate a CMS by "filtering" the URLs before the finished HTML page is served.

URL replacement by regex, BeautifulSoup, or whatever

Each URL is replaced as follows:

   <img src="https://foo.com/bar.gif" />
-> <img src="<?php echo cdn( "bar.gif" ); ?>" />

This will also work:

   <img onclick="myFunction('https://foo.com/bar.gif')" />
-> <img onclick="myFunction('<?php echo cdn( "bar.gif" ); ?>')" />

However, for CSS, PHP parsing cannot happen inside quotes. Instead, replace the whole value:

   background-image: url('https://foo.com/bar.gif');
-> background-image: <?php echo sprintf( "url('%s');", cdn( "bar.gif" ); ?>

CDN function

The actual code for cdn is stored centrally at the file root, and assumes a local URL is passed:

const CDN_LOCAL = 'https://foo.com';
const CDN_OFFSITE = 'https://cdn.foo.com';
const CDN_EXTS = array( 'gif', 'png', 'jpg' ); // (etc.; maybe 20 exts)

function cdn( $url ) {
    $url = trim($url);

    $parts = explode('.', $url);
    $ext = $parts[count($parts) - 1];

    $base = ( in_array ( $ext, CDN_EXTS ) ) ? CDN_OFFSITE : CDN_LOCAL;

    $url = sprintf( '%s/%s', $new_base, $url );
    return $url;
}

Naturally, this means that every file must also require this one:

require_once( '/home/username/public_html/cdn.php' );

Handling non-PHP files

An extra complication is that a server with a bunch of HTML and CSS files will need to know to handle those as PHP. This .htaccess rule does the trick:

AddType application/x-httpd-php5 .html .htm .css

Each file will then need to declare headers, though not if included elsewhere. This line is added during the regex step. The Content-type and charset are then filled in dynamically; these are just examples:

<?php if ( ! headers_sent() ) header( "Content-type:text/html; charset=utf-8" ); ?>

Combined, these steps did the trick. :) Advantage: If the CDN location changes or a future team decides to cancel the service, it will be easy to alter cdn.php's constants (or behaviour) to nullify this. Also, the steps used to make these URLs dynamic could fairly easy be reversed by regex and the .htaccess rules removed if someone wanted to undo this.

Luke Sawczak
  • 239
  • 4
  • 13