• Stars
    star
    204
  • Rank 185,032 (Top 4 %)
  • Language
    JavaScript
  • Created about 11 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Versions, A small module for creating a flexible CDN application

versions

Versions is a simple but powerful node.js module that allows you to create a flexible static server or content delivery network. Serving static assets is a pain in Node, it's not something it focuses on and everybody advises you to setup a static server using NGINX or implement a cache proxying using Varnish or Squid. The biggest advantage that these servers have is that they support sendfile for sending static assets and is generally agreed upon that this is "The Best" method for sending static data. But Node doesn't have this advantage, it's removed from the core "due to reasons" and the only way to get decent file serving performance is to do aggressive caching of the assets in memory to reduce I/O operations as well as optimize for cache hits inside the browser or using conditional requests. And that is the goal of this project, cache all the things!

Build status

Please note that the build status only displays the status of the GitHub master branch. New stable versions are only released once the master passes all tests.

Build Status


Features

Versions comes with tons of features to make it easier for you to set up a simple static server. We try to support as many features as a normal paid CDN would provide for you.

Origin Pull

In addition to serving files from disk you can also configure versions to pull static content from an origin server. This way you don't have to upload you static assets to a separate server in order to get them cached.

Set caching headers for files

In order to reduce the amount of HTTP requests that a browser would do for your files, versions automatically sets the appropriate caching headers. This way you assets will be served from the browser cache instead of the server.

Advanced gzipping

Gzip is enabled on every compatible file format, even if the origin server doesn't support gzip. In addition to that, we have disabled gzip for IE 5 and IE6 without service pack 2 as it is known to improperly cache it. We also have detection for obfuscated gzip headers as researched by the Yahoo performance team.

REST API for managing your server

You can communicate with the server using a REST API. You can inspect items from the cache, see what keys are cached or flush the server. The possibilities are endless.

Metrics

Everybody loves stats, that's why we are gathering metrics about the requests and the state of the server. These metrics can be accessed through the REST API.

Client API

Versions comes with a dedicated client that can communicate with it's REST API's or through Pub/Sub.

Synchronisation

Synchronises configuration and versions number between different connected consumers to ensure that they are all hitting the same cached version.

Love

It's crafted and engineered with love, what else do you need?


Installation

Installation is done through the node package manager (npm)

npm install versions --save

The --save tells npm to automatically add this file to the dependencies object of your package.json file.

API references

The API references are generated from the source's JSDoc comments:

Configuration

The server can be configured in 2 different ways or a hybrid of both. It has a dedicated configuration file called versions.json that lives in the root of your application folder (the application folder is the folder that contains your node_modules folder). But you can also configure the module through a chainable API. And the last would be a hybrid of those. Using a configuration file and using the API to override some of the configuration values.

auth

The auth property is a simple security token that you can use to secure your versions REST API. After setting this property it requires an ?auth= parameter to be used to access the API.

<pre>versions.set('auth', 'Sup3rSecr3tP4z5w0rdy0');</pre>
blacklisted extensions

Black list extensions that you do not want to have pulled from your origin server. You can for example black list .conf files or maybe some other random files. Please note that people can still fetch these files directly from the origin server.

<pre>versions.set('blacklisted extensions', ['.conf', '.log', '.gz']);</pre>
cors

Set custom Access-Control-Allow-Origin headers. The default value is * so all values are allowed. If you only want to allow access from a specific domain set the domain here.

<pre>versions.set('cors', '*.example.com');</pre>
directory

A directory that is relative to the module that required versions that is used to serve static content. If you want this directory to be relative to a different path. You can set a root property.

<pre>versions.set('directory', './public');</pre>
force extensions

Only allow files with an extension to be pulled from origin servers. The reason behind this is that you might set your own site as full origin and that would mean that your regular pages would also be proxied by versions and create duplicate content. It's much less common that .html are served. Thats why we force extensions by default.

<pre>versions.set('force extensions', false);</pre>
ignore querystring

Ignore the querystring when generating the cache key. When you use querystring parameters that are not used on the server, including the querystring in the cache key would bypass the cache every time. Setting this option to true, the cache key is only generated from the requested pathname. Because in most cases this behavior is unwanted, this to false.

<pre>versions.set('ignore querystring', false);</pre>
expire internal cache

How long should we keep items in our internal (memory) cache. It accepts a numeric value as milliseconds or a human readable string like 10 hours or 90 minutes. Defaults to 1 hour.

<pre>versions.set('expire internal cache', '2 days');</pre>
max age

How long should the browser cache the files? It accepts a numeric value as miliseconds or a human readable string like 10 hours or 90 days. Defaults to 30 days. Please note that this value should not be longer then a year.

<pre>versions.set('max age', '1 year')</pre>
port

As you might imagine, on which port number do you want to run the server. Defaults to 8080.

<pre>versions.set('port', '8080');</pre>
origin servers

An array of of server objects that is used to fetch resources that are not found in the directory property.

<pre>versions.set('origin servers', { url: "http://example.com", name: "foo" });</pre>
version

The version number of the cache that can be automatically increased and synced between clients so cache can be expired on demand and still have the same version number/cache hits between different clients.

<pre>versions.set('version', '0.0.0');</pre>
aliases

In order to parallelize the downloading of assets in the browser they should be spread across multiple subdomains/domains. You can supply multiple origin servers that the client will use to distribute the assets.

<pre>versions.set('aliases', 'http://example.org');</pre>
log level

As versions is intended to run as a standalone server it comes with a logger that outputs some useful information. You can control the amount of output by changing the log level. The default value is log. Please check the dev/null node.js logger for the supported log levels.

<pre>versions.set('log level', 'debug');</pre>
plugins

Versions is built on top of the connect framework and is configured to use the minimal amount of plugins to get the job done. The plugins array allows you to specify extra middleware layers that you want to have loaded into versions or custom connect compatible nodejs modules that need to be required.

<pre>versions.set('plugins', [{ name: 'logger', config: 'short' }, 'logger']);</pre>
sync

Synchronise configuration between client and server. If you are using multiple servers also set the redis configuration.

<pre>versions.set('sync', true);</pre>
redis

In order to enable a truely distributed cache cloud you can opt in to use a Redis back-end for syncing purposes. Note this requires `redis` to be installed as submodule of the main project that is using versions. This object accepts the following properties:

<ul>
  <li>
    <strong>host</strong>
    The host name of your redis server.
  </li>
  <li>
    <strong>port</strong>
    The port number of your redis server.
  </li>
  <li>
    <strong>auth</strong>
    Optional auth/password to access your redis server.
  <li>
    <strong>namespace</strong>
    The key that should be used to store the configuration and be used as the
    channel name for the pub/sub channel. Defaults to <code>versions</code>
  </li>
</ul>

versions.json

When you require the versions module it will try to find a versions.json (or versions.js with a module.exports pattern) file in your root folder and use this as default configuration.

{
  "auth": "my-secret-auth-key",
  "blacklisted extensions": [".foo", ".conf"],
  "cors": "*",
  "directory": "./public",
  "expire internal cache": "1 hour",
  "max age": "30 days",
  "origin servers": [
    { "url": "https://www.nodejitsu.com", "id": "home" },
    { "url": "https://webops.nodejitsu.com", "id": "webops" }
  ],
  "port": 8080,
  "plugins": [
    "logger",
    "custom-nodejs-module",
    { 
      "name": "custom-nodejs-module",
      "config": {
        "custom": "configuration options that will be feed in to the middleware"
      }
    }
  ]
}

Configuration API

In addition to reading your versions.json file for the configuration it is also possible to set the configuration using dedicated API methods or the versions#set method. The versions#set method expects 2 arguments, the first argument is the name of the configuration key that you want to update and the second value is the actual value:

var versions = require('versions');

versions.set('auth', 'superSec3rtp4ssw0rd')

The API is also chainable, so you can do as many versions#set calls if needed. Versions also provides you with some API sugar to make configuring a bit more human readable:

versions.path('/public').expire('10 hours').set('sync', true);

The following API methods map directly to configuration (see versions.json configuration above for detailed information about what each configuration key triggers):

API Configuration key
path directory
lifetime max age
expire expire internal cache

Server example

'use strict';

// require versions, if you have `versions.json` in the same folder as your
// `package.json` it will load that as default configuration for you
var versions = require('versions');

// If you don't have a versions.json or want to override some values:
versions.set('log level', 'debug')
        .set('auth', 'helloW0nderW0man');

// Or use some of the nicer API sugar
versions.path('./public').lifetime('30 days').expire('10 hours');

// After you have configured everything that you want just start listening on
// the server.
versions.listen(8080);

But it can be much shorter if you don't have to overide any configuration from your versions.json file:

require('versions').listen();

Rest API

GET /flush

Completely removes the internal cache. This does not flush cache-headers for the HTTP requests.

Returns:

{
  flush: 'OK'
}

GET /expire?key=

Removes the matched item(s) from the internal cache. It uses the value of ?key=key to find and match it against request URLS in the cache.

Returns:

{
  expire: 'OK',
  expired: 1
}

GET /inspect?key=

Finds the item in the cache and displays some information about it, like the total size of gzip, content-length etc.

Returns:

{
  key: 'name of the key',
  data: {
    'Content-Length': 0,
    'Content-Length Gzip': 0,
    'Content-Type': 'text/html',
    'Last-Modified': 'Sun, 31 Mar 2013 13:37:33 GMT'
  }
}

Or when a given key is not found:

{ inspect: 'Failed to find the requested key file in cache' }

GET /keys

Lists all items that are currently in the cache.

Returns:

{
  keys: [
    "versions:0.1.14#/css/jitsu.min.css",
    "#/id:home/img/sprite.png",
    "versions:0.1.14#/js/jitsu.min.js",
    "#/id:home/img/nodepm.png",
    "versions:0.1.14#/js/cortex.min.js",
    "#/id:home/img/trusted.png",
    "#/id:home/img/cloud.png",
    "#/id:home/webfonts/ss-standard.woff",
    "#/id:home/webfonts/ss-social-regular.woff",
    "#/id:home/webfonts/ss-social-circle.woff",
    "#/id:home/img/spinner.gif"
  ]
}

GET /version

Get the current version of internal cache.

Returns:

{ versions: '0.0.0' }

POST/PUT /version

Update the server to a new version number, if Redis sync is also the changes will also be synced with other instances.

Returns:

{ versions: '0.0.0' }

Or when no body is send:

{ error: 'Invalid body' }

GET /metrics

Returns a bunch of metrics.

License

MIT

More Repositories

1

memcached

A fully featured Memcached client build on top of Node.js. Build with scaling in mind so it will support Memcached clusters and consistent hashing.
JavaScript
1,312
star
2

useragent

Useragent parser for Node.js, ported from browserscope.org
JavaScript
886
star
3

node-hashring

hashring is a consistent hashing algorithm for Node.js that is compatible with libketama and python's hash_ring package
JavaScript
349
star
4

licensing

Discover the license footprint of your application
JavaScript
87
star
5

jackpot

Jackpot, tcp connection pooling for Node.js
JavaScript
75
star
6

creditcard

Creditcard number parsing, validation and information extraction
JavaScript
60
star
7

npmjs

An alternative npm registry client that I like.
JavaScript
49
star
8

argh

argh is a extremely light weight option/argument/process.argv parser for Node.js. It only parses options, nothing more than that.
JavaScript
45
star
9

FlashPolicyFileServer

A simple Flash Policy File Server for node
JavaScript
39
star
10

diagnostics

Tools for debugging your node.js modules
JavaScript
34
star
11

load

Load JavaScript files that do not use the bloat module patterns
JavaScript
24
star
12

cluster.exception

Exception handler for cluster
JavaScript
23
star
13

kuler

Color your terminal using CSS/hex color codes
JavaScript
21
star
14

realtimeplatform.github.com

TBA
21
star
15

licenses

Retrieve accurate license information for a given npm package.
JavaScript
21
star
16

fs.notify

File change notification that doesn't suck hairy monkey balls and just works.
JavaScript
19
star
17

canihaz

canihaz, lazy installing node.js modules
JavaScript
19
star
18

expirable

Expirable cache for node.js, FUCKING AWESOME YO!
JavaScript
18
star
19

mana

Mana allows api-oriented clients greater stability and high availability in demanding distributed battles and boss fights.
JavaScript
16
star
20

fingerprinting

Produce a unique string for any given resource, commonly used in cache busting practices.
JavaScript
11
star
21

nodejsconfit-2011

Demo's from nodejsconf 2011
JavaScript
11
star
22

find-package-json

Find package.json files in parent directories using an iterator based API. Keep searching till you find the one you're looking for or when you run out of folders to search in.
JavaScript
11
star
23

renderme

Render README files that people use on Github
JavaScript
10
star
24

one-time

Run the supplied function exactly one time (once).
JavaScript
9
star
25

.files

The . files, vim & build commands etc
Vim Script
9
star
26

shrinkwrap

npm shrinkwrap parsing, generation and comparison
JavaScript
9
star
27

text-hex

Create a hash from a string of text and transforms it to a color
JavaScript
8
star
28

env-variable

Cross platform environment variables with process.env, window.name, location.hash and localStorage fallbacks
JavaScript
7
star
29

commenting

Wrap content in a comment that is valid for a given file type.
JavaScript
7
star
30

node-bisection

Bisection algorithm for node.js
JavaScript
7
star
31

fn.name

Extract the name from a function.
JavaScript
7
star
32

senpai

Notice me senpai! A graceful degrading notification system for browsers.
JavaScript
7
star
33

memcached-stream

High performance streaming memcached protocol parser for Node.js. Code name: flaming-octo-bear
JavaScript
6
star
34

node-algorithms

A series of algorithms ported to JavaScript to be used on Node.js
JavaScript
5
star
35

koekje

A sessionStorage interface for cookies
JavaScript
5
star
36

uni

uni[versal] command line
JavaScript
5
star
37

ansidown

Convert a subset of markdown do a somewhat ANSI compatible output
JavaScript
5
star
38

failover

cluster-fuck management
JavaScript
4
star
39

Spry-Configurator

Spry files configurator and combinator. Version 2.0 is currently running on config-spry-it.com
JavaScript
4
star
40

gjallarhorn

Child process management without blasting your server in to pieces.
JavaScript
3
star
41

setup-env

Automated, feature detected, environment setup for your test suite
JavaScript
3
star
42

jQuery-scrollector

Navigate to elements using hashtag based CSS3 selectors,
JavaScript
3
star
43

odoyle

Micro Rules Engine powered by a simple JSON structure
JavaScript
3
star
44

connected

Simple wrapper to ensure that your `server.listen` calls receive an err like all regular callback signatures.
JavaScript
3
star
45

woohoo

WooHoo is Celebration as a Service.
JavaScript
3
star
46

assign

Map/Reduce promise like returned API -- Really not way to properly describe this module..
JavaScript
3
star
47

YUNO-UPDATE

Y U NO update your browser
JavaScript
3
star
48

enabled

Check if a certain flag is enabled.
JavaScript
3
star
49

colorspace

Generate HEX colors for a given namespace.
JavaScript
3
star
50

mono-repos

Highly opinionated set of utilities to orchestrate and administrate mono repositories.
JavaScript
3
star
51

queueback

Callback queue system for optimizing your HTTP requests
JavaScript
3
star
52

require-poisoning

Cache-Poisoning applied to Node.js require statements so you inject your own modules
JavaScript
3
star
53

rip-out

Rip out properties from an object that you don't want to have included in the cloned result.
JavaScript
2
star
54

setHeader

Protect headers from being overridden before they are written to response.
JavaScript
2
star
55

Outside

Go Outside to chat
JavaScript
2
star
56

package-link

npm link that doesn't suck
JavaScript
2
star
57

shrubbery

Shrubbery is small Map() backed plugin registry
JavaScript
2
star
58

treason

Cheating on React's JSX by using JSON
JavaScript
2
star
59

booting

Async Initialization Process
JavaScript
2
star
60

darknode

HTTP/Docker interface for Darkweb/yolo
JavaScript
2
star
61

storage-engine

EventEmitter abstraction on top the React-Native AsyncStorage API
JavaScript
2
star
62

connection-parse

Simple TCP connection string parser
JavaScript
2
star
63

enu

Extract enumerable and non-enumerable properties from an object.
JavaScript
2
star
64

node-browserscope

Browerscope.org results based on user agent queries
JavaScript
2
star
65

dollars

The "write less, do more, save dollars" library
JavaScript
2
star
66

timbers

Shiver me timbers! A tool to map short CLI argument to long CLI arguments
JavaScript
1
star
67

debug.css

debug.css
1
star
68

argh-matey

Argh Matey allows you to easily find the right cli command using language processing.
JavaScript
1
star
69

truth

Data is the only source of truth.
JavaScript
1
star
70

sparklet

Sparklet is a sparkline pagelet for BigPipe
JavaScript
1
star
71

window.name

A module which exposes sessionStorage API for storing data in the window.name
JavaScript
1
star
72

parser

Redis based IRC protocol parser based on lua scripting
Lua
1
star
73

platform-specific

Platform specific information for isomorphic applications
JavaScript
1
star
74

nock-knock

Advanced router handling for nock
JavaScript
1
star
75

dotfig

Configuration extraction from dot files or package.json fields
JavaScript
1
star
76

Spry-UI-ProgressBar

Progress bar widget for the Spry Framework
JavaScript
1
star
77

orbited

JavaScript
1
star
78

all-the-things

Random development of all the things, which should not be published yet, but does need to be tested
JavaScript
1
star
79

zoidberg

Flow control? Why not zoidberg
JavaScript
1
star
80

Spry-YQL-DataSet

YQL for Spry Data Sets
JavaScript
1
star
81

send-help

Generate developer friendly output of a help command based on a given object structure.
JavaScript
1
star