Since I started using nearlyfreespeech.net 3 months ago, I've been very pleased. Getting them to set up access with a private key was straightforward and the email support person was prompt, helpful and friendly. The only downsides are the safe mode restrictions, which I have been easily able to work around, and the expensive storage ($1/MB/month), which would add up quickly with all the icons and fonts I'm serving with the webservices.
So I put them onto Amazon's S3 at bililite.s3.amazonaws.com with the intent of using that like a Content Delivery Network (though it isn't really unless I pay for CloudFront as well)—static, large files should come tranparently from S3 while the dynamic site runs on NFS.net.
I do this with a bit of .htaccess
hackery. It's harder to create or modify files on S3, so files that are in active developement are on the webserver. I want to serve those files if they exist. Only if the desired files do not exist do I want to get them from S3. Unfortunately, NFS.net does not support mod_proxy
, so the redirecting is not transparent (and we can't do things that require same-origin security). But for images and the like, this works:
SetEnvIf Request_URI . CDN=http://bililite.s3.amazonaws.com RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} ^/(images|inc|fonts)/ RewriteRule . %{ENV:CDN}%{REQUEST_URI}
Line 1 creates a variable named CDN
. The directive SetEnv
would be more natural to use as SetEnv CDN http://bililite.s3.amazonaws.com
, but URL rewriting is done before SetEnv
runs. The newer SetEnvIf
runs early enough for the variable to be used for rewriting, but it's conditional, so we use a dummy condition: REQUEST_URI .
, which means "If the requested URI matches any character"
Line 4 tests whether the requested file exists on the server. Only if it does not exist (!-f
) is the next line tested, which is whether the file is in any of the CDN directories.
If it is to be redirected, create the new URL by concatenating the CDN
variable with the requested URI, which does not contain the protocol or hostname. Thus http://bililite.com/images/silk/add.png
has a REQUEST_URI
of /images/silk/add.png
and the rewritten URL is http://bililite.s3.amazonaws.com/images/silk/add.png
.
The advantage of setting a variable in the .htaccess
(aside from having the "magic constant" at the top of the file") is that this is passed to the PHP code as imagecreatefrompng($_SERVER['CDN'].'/images/silk/add.png')
. So the name of the S3 server is written in just one place, with no need to change multiple files if it changes.