Cold FeetUser Guide
Overview
Cold Feet is a support library that aids Alien-Factory in the development of other libraries, frameworks and applications. Though you are welcome to use it, you may find features are missing and the documentation incomplete.
Cold Feet
is an asset caching strategy for your Bed App.
- Tired of telling clients to clear their browser cache to pick up the latest CSS and Javascript changes?
- Don't want lame browser cache busting because you need network performance?
- Then get
Cold Feet
!
Install
Install Cold Feet
with the Fantom Repository Manager ( fanr ):
C:\> fanr install -r http://repo.status302.com/fanr/ afColdFeet
To use in a Fantom project, add a dependency to build.fan
:
depends = ["sys 1.0", ..., "afColdFeet 1.2+"]
Documentation
Full API & fandocs are available on the Status302 repository.
Quick Start
1). Create a text file called Example.fan
:
using afIoc using afBedSheet using afColdFeet class Example { @Inject PodHandler? podHandler Text coldFeetUrls() { asset := podHandler.fromPodResource(`fan://icons/x256/flux.png`) msg := " Normal URL: ${asset.localUrl} \n" msg += "Cold Feet URL: ${asset.clientUrl}\n" return Text.fromPlain(msg) } } @SubModule { modules=[ColdFeetModule#] } class AppModule { @Contribute { serviceType=Routes# } static Void contributeRoutes(Configuration conf) { conf.add(Route(`/`, Example#coldFeetUrls)) } } class Main { Int main() { afBedSheet::Main().main([AppModule#.qname, "8080"]) } }
2). Run Example.fan
as a Fantom script from the command line. This starts the BedSheet app server:
C:\> fan Example.fan ___ __ _____ _ / _ | / /_____ _____ / ___/__ ___/ /_________ __ __ / _ | / // / -_|/ _ /===/ __// _ \/ _/ __/ _ / __|/ // / /_/ |_|/_//_/\__|/_//_/ /_/ \_,_/__/\__/____/_/ \_, / Alien-Factory BedSheet v1.3.14, IoC v1.7.6 /___/ IoC Registry built in 612ms and started up in 104ms Bed App 'Unknown' listening on http://localhost:8080/
3). Visit http://localhost:8080/
Normal URL: /pods/icons/x256/flux.png d Feet URL: /coldFeet/infYBQ==/pods/icons/x256/flux.png<pre
Usage
Contribute your asset directories to the BedSheet FileHandler service as usual, but rather than hard-coding the asset URLs, let the FileHandler
service generate them for you.
Cold Feet
invisibly instruments the FileHandler
service to add a caching strategy to the generated client URLs. An asset URL such as `/css/myStyles.css`
magically becomes a Cold Feet
URL like `/coldFeet/XXXX/css/myStyles.css`
, where:
/coldFeet
is a prefix used to identify the URL on incoming requests./XXXX
is a digest, generated by Cold Feet, that changes when the asset content changes.
When a request is made for the asset using the modified URL, Cold Feet
intercepts the request using BedSheet middleware and serves up the file.
Cold Feet
lets the browser aggressively cache these files by setting a far-future expiration header on it (1 year by default). Note this expiration header is only enabled in production; see IoC Env.
If during that 1 year the asset is modified then the Cold Feet
URL will change, just as the XXXX
digest changes. This forces the browser to download the new asset.
The smart ones amongst you will be asking, "But what if the browser requests an old asset URL?" Simple, Cold Feet
recognises outdated URLs and responds with a 308 - Moved Permanently
redirecting the browser to the new asset URL.
What Usage?
Because Cold Feet
works in the background, invisibly advising the FileHandler
and PodHandler
services, there is no Cold Feet Usage per se. Just add Cold Feet
as a project dependency and optionally configure a digest.
Then use FileHandler
and PodHandler
to generate client URLs to your files, and use them your web pages.
You may also prevent ColdFeet
from altering subsets of URLs by contributing regular expressions to UrlExclusions
. Example, to make ColdFeet
ignore all files in the directory images/
:
@Contribute { serviceType=UrlExclusions# } static Void contributeUrlExclusions(Configuration config) { config.add("^/images/".toRegex) }
Digest Strategies
Adler-32
This is the default strategy used by Cold Feet
. It calculates a digest with the Adler-32 checksum algorithm. The checksum is then Base-64 encoded using the URL and filename safe alphabet.
The Adler-32 checksum was designed for speed and created for use in the zlib compression library which makes it an ideal fit for an asset digest.
Note that if your CSS file has a relative URL in it, such as:
.pretty-div { background-image: url(../images/pretty.png); }
Then, under Adler-32, it will be served under the wrong digest. This is because if your CSS file is served under:
/coldFeet/x9x9x9/css/styles.css
The browser will resolve pretty.png
to be under the same digest path:
/coldFeet/x9x9x9/css/../images/pretty.png
This won't do any harm, as Cold Feet
will simply redirect the browser to the correct URL, but the redirect is a wasted round trip. As each redirect creates a warning, monitor your logs to find any missed relative URLs and correct as necessary. If there are many, you may wish to preprocess your CSS files to generate the Cold Feet URLs before serving.
App Version
This simple strategy ignores the asset file in question and instead returns the application's pod version. Thus, when a new application is deployed (with an new version), clients will re-download all the assets.
When not in production mode, the digest defaults to a random string.
To use, override the default digest strategy in your AppModule
:
class AppModule { @Contribute { serviceType=ServiceOverrides# } static Void contributeOverrides(Configuration config) { config[DigestStrategy#] = AppVersionDigest() } }
Fixed Value
Use this strategy in testing. It returns a fixed / constant value each and every time.
To use, override the default digest strategy in your AppModule
:
class AppModule { @Override static DigestStrategy overrideDigestStrategy() { FixedValueDigest("XXX") } }
Release Notes
v1.2.8
- New: Contribute regular expressions to
UrlExclusions
to exclude URLs from being handled / altered by ColdFeet.
v1.2.6
- Chg: Updated to use IoC 2.0.0.
v1.2.4
- New: Cold Feet now also provides an asset caching strategy for pod resources.
- Chg: Updated to use IoC 1.7.6 and BedSheet 1.3.14.
v1.2.2
- New: Added a far future
Cache-Control
HTTP response header. - Chg: Updated to use IoC 1.7.2 and BedSheet 1.3.12.
- Chg: Reduced
assetExpiresIn
to 1 year as per RFC 2616 Guidelines.
v1.2.0
- New:
Cold Feet
now invisibly instruments / advises BedSheet'sFileHandler
service so it returns asset caching URLs! - Chg: Removed
ColdFeet
service as it is no longer needed. Use BedSheet'sFileHandler
instead. - Chg: Updated to use BedSheet 1.3.10.
v1.1.4
- New: Adler-32 digests are cached so they aren't re-calculated on every request. (Uses BedSheet's new
FileMetaCache
service.) - Chg: Updated to use BedSheet 1.3.8.
v1.1.2
- Chg: Updated to use IoC 1.6.0 and BedSheet 1.3.6.
- Bug: Urls with query params were not accepted.
- Bug: Corrected problems with redirecting on incorrect digest.
v1.1.0
- New: Added the Alder-32 digest strategy.
- Chg: Renamed
ChecksumStrategy
->DigestStrategy
and renamed the implmentations to suit. - Chg: Renamed the
ColdFeet
service methods to match those in BedSheet'sFileHandler
. - Chg: All redirects are logged as warnings (complete with the referer). This allows you to find any missed relative references.
v1.0.0
- New: Added
assetExpiresIn
config value - defaults to 10 years. - Chg: Uses new
FileHandler
methods in BedSheet 1.3.4.
v0.0.2
- New: Preview Release