diff --git a/lib/document_handler.js b/lib/document_handler.js deleted file mode 100644 index 14da9b2..0000000 --- a/lib/document_handler.js +++ /dev/null @@ -1,155 +0,0 @@ -var winston = require('winston'); -var Busboy = require('busboy'); - -// For handling serving stored documents - -var DocumentHandler = function(options) { - if (!options) { - options = {}; - } - this.keyLength = options.keyLength || DocumentHandler.defaultKeyLength; - this.maxLength = options.maxLength; // none by default - this.store = options.store; - this.keyGenerator = options.keyGenerator; -}; - -DocumentHandler.defaultKeyLength = 10; - -// Handle retrieving a document -DocumentHandler.prototype.handleGet = function(request, response, config) { - const key = request.params.id.split('.')[0]; - const skipExpire = !!config.documents[key]; - - this.store.get(key, function(ret) { - if (ret) { - winston.verbose('retrieved document', { key: key }); - response.writeHead(200, { 'content-type': 'application/json' }); - if (request.method === 'HEAD') { - response.end(); - } else { - response.end(JSON.stringify({ data: ret, key: key })); - } - } - else { - winston.warn('document not found', { key: key }); - response.writeHead(404, { 'content-type': 'application/json' }); - if (request.method === 'HEAD') { - response.end(); - } else { - response.end(JSON.stringify({ message: 'Document not found.' })); - } - } - }, skipExpire); -}; - -// Handle retrieving the raw version of a document -DocumentHandler.prototype.handleRawGet = function(request, response, config) { - const key = request.params.id.split('.')[0]; - const skipExpire = !!config.documents[key]; - - this.store.get(key, function(ret) { - if (ret) { - winston.verbose('retrieved raw document', { key: key }); - response.writeHead(200, { 'content-type': 'text/plain; charset=UTF-8' }); - if (request.method === 'HEAD') { - response.end(); - } else { - response.end(ret); - } - } - else { - winston.warn('raw document not found', { key: key }); - response.writeHead(404, { 'content-type': 'application/json' }); - if (request.method === 'HEAD') { - response.end(); - } else { - response.end(JSON.stringify({ message: 'Document not found.' })); - } - } - }, skipExpire); -}; - -// Handle adding a new Document -DocumentHandler.prototype.handlePost = function (request, response) { - var _this = this; - var buffer = ''; - var cancelled = false; - - // What to do when done - var onSuccess = function () { - // Check length - if (_this.maxLength && buffer.length > _this.maxLength) { - cancelled = true; - winston.warn('document >maxLength', { maxLength: _this.maxLength }); - response.writeHead(400, { 'content-type': 'application/json' }); - response.end( - JSON.stringify({ message: 'Document exceeds maximum length.' }) - ); - return; - } - // And then save if we should - _this.chooseKey(function (key) { - _this.store.set(key, buffer, function (res) { - if (res) { - winston.verbose('added document', { key: key }); - response.writeHead(200, { 'content-type': 'application/json' }); - response.end(JSON.stringify({ key: key })); - } - else { - winston.verbose('error adding document'); - response.writeHead(500, { 'content-type': 'application/json' }); - response.end(JSON.stringify({ message: 'Error adding document.' })); - } - }); - }); - }; - - // If we should, parse a form to grab the data - var ct = request.headers['content-type']; - if (ct && ct.split(';')[0] === 'multipart/form-data') { - var busboy = new Busboy({ headers: request.headers }); - busboy.on('field', function (fieldname, val) { - if (fieldname === 'data') { - buffer = val; - } - }); - busboy.on('finish', function () { - onSuccess(); - }); - request.pipe(busboy); - // Otherwise, use our own and just grab flat data from POST body - } else { - request.on('data', function (data) { - buffer += data.toString(); - }); - request.on('end', function () { - if (cancelled) { return; } - onSuccess(); - }); - request.on('error', function (error) { - winston.error('connection error: ' + error.message); - response.writeHead(500, { 'content-type': 'application/json' }); - response.end(JSON.stringify({ message: 'Connection error.' })); - cancelled = true; - }); - } -}; - -// Keep choosing keys until one isn't taken -DocumentHandler.prototype.chooseKey = function(callback) { - var key = this.acceptableKey(); - var _this = this; - this.store.get(key, function(ret) { - if (ret) { - _this.chooseKey(callback); - } else { - callback(key); - } - }, true); // Don't bump expirations when key searching -}; - -DocumentHandler.prototype.acceptableKey = function() { - return this.keyGenerator.createKey(this.keyLength); -}; - -module.exports = DocumentHandler; diff --git a/lib/document_stores/amazon-s3.js b/lib/document_stores/amazon-s3.js deleted file mode 100644 index 11dd85d..0000000 --- a/lib/document_stores/amazon-s3.js +++ /dev/null @@ -1,56 +0,0 @@ -/*global require,module,process*/ - -var AWS = require('aws-sdk'); -var winston = require('winston'); - -var AmazonS3DocumentStore = function(options) { - this.expire = options.expire; - this.bucket = options.bucket; - this.client = new AWS.S3({region: options.region}); -}; - -AmazonS3DocumentStore.prototype.get = function(key, callback, skipExpire) { - var _this = this; - - var req = { - Bucket: _this.bucket, - Key: key - }; - - _this.client.getObject(req, function(err, data) { - if(err) { - callback(false); - } - else { - callback(data.Body.toString('utf-8')); - if (_this.expire && !skipExpire) { - winston.warn('amazon s3 store cannot set expirations on keys'); - } - } - }); -} - -AmazonS3DocumentStore.prototype.set = function(key, data, callback, skipExpire) { - var _this = this; - - var req = { - Bucket: _this.bucket, - Key: key, - Body: data, - ContentType: 'text/plain' - }; - - _this.client.putObject(req, function(err, data) { - if (err) { - callback(false); - } - else { - callback(true); - if (_this.expire && !skipExpire) { - winston.warn('amazon s3 store cannot set expirations on keys'); - } - } - }); -} - -module.exports = AmazonS3DocumentStore; diff --git a/lib/document_stores/file.js b/lib/document_stores/file.js deleted file mode 100644 index 7fd5995..0000000 --- a/lib/document_stores/file.js +++ /dev/null @@ -1,63 +0,0 @@ -var fs = require('fs'); -var crypto = require('crypto'); - -var winston = require('winston'); - -// For storing in files -// options[type] = file -// options[path] - Where to store - -var FileDocumentStore = function(options) { - this.basePath = options.path || './data'; - this.expire = options.expire; -}; - -// Generate md5 of a string -FileDocumentStore.md5 = function(str) { - var md5sum = crypto.createHash('md5'); - md5sum.update(str); - return md5sum.digest('hex'); -}; - -// Save data in a file, key as md5 - since we don't know what we could -// be passed here -FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) { - try { - var _this = this; - fs.mkdir(this.basePath, '700', function() { - var fn = _this.basePath + '/' + FileDocumentStore.md5(key); - fs.writeFile(fn, data, 'utf8', function(err) { - if (err) { - callback(false); - } - else { - callback(true); - if (_this.expire && !skipExpire) { - winston.warn('file store cannot set expirations on keys'); - } - } - }); - }); - } catch(err) { - callback(false); - } -}; - -// Get data from a file from key -FileDocumentStore.prototype.get = function(key, callback, skipExpire) { - var _this = this; - var fn = this.basePath + '/' + FileDocumentStore.md5(key); - fs.readFile(fn, 'utf8', function(err, data) { - if (err) { - callback(false); - } - else { - callback(data); - if (_this.expire && !skipExpire) { - winston.warn('file store cannot set expirations on keys'); - } - } - }); -}; - -module.exports = FileDocumentStore; diff --git a/lib/document_stores/google-datastore.js b/lib/document_stores/google-datastore.js deleted file mode 100644 index 76fc827..0000000 --- a/lib/document_stores/google-datastore.js +++ /dev/null @@ -1,89 +0,0 @@ -/*global require,module,process*/ - -const Datastore = require('@google-cloud/datastore'); -const winston = require('winston'); - -class GoogleDatastoreDocumentStore { - - // Create a new store with options - constructor(options) { - this.kind = "Haste"; - this.expire = options.expire; - this.datastore = new Datastore(); - } - - // Save file in a key - set(key, data, callback, skipExpire) { - var expireTime = (skipExpire || this.expire === undefined) ? null : new Date(Date.now() + this.expire * 1000); - - var taskKey = this.datastore.key([this.kind, key]) - var task = { - key: taskKey, - data: [ - { - name: 'value', - value: data, - excludeFromIndexes: true - }, - { - name: 'expiration', - value: expireTime - } - ] - }; - - this.datastore.insert(task).then(() => { - callback(true); - }) - .catch(err => { - callback(false); - }); - } - - // Get a file from a key - get(key, callback, skipExpire) { - var taskKey = this.datastore.key([this.kind, key]) - - this.datastore.get(taskKey).then((entity) => { - if (skipExpire || entity[0]["expiration"] == null) { - callback(entity[0]["value"]); - } - else { - // check for expiry - if (entity[0]["expiration"] < new Date()) { - winston.info("document expired", {key: key, expiration: entity[0]["expiration"], check: new Date(null)}); - callback(false); - } - else { - // update expiry - var task = { - key: taskKey, - data: [ - { - name: 'value', - value: entity[0]["value"], - excludeFromIndexes: true - }, - { - name: 'expiration', - value: new Date(Date.now() + this.expire * 1000) - } - ] - }; - this.datastore.update(task).then(() => { - }) - .catch(err => { - winston.error("failed to update expiration", {error: err}); - }); - callback(entity[0]["value"]); - } - } - }) - .catch(err => { - winston.error("Error retrieving value from Google Datastore", {error: err}); - callback(false); - }); - } -} - -module.exports = GoogleDatastoreDocumentStore; diff --git a/lib/document_stores/memcached.js b/lib/document_stores/memcached.js deleted file mode 100644 index 844e267..0000000 --- a/lib/document_stores/memcached.js +++ /dev/null @@ -1,54 +0,0 @@ -const memcached = require('memcached'); -const winston = require('winston'); - -class MemcachedDocumentStore { - - // Create a new store with options - constructor(options) { - this.expire = options.expire; - - const host = options.host || '127.0.0.1'; - const port = options.port || 11211; - const url = `${host}:${port}`; - this.connect(url); - } - - // Create a connection - connect(url) { - this.client = new memcached(url); - - winston.info(`connecting to memcached on ${url}`); - - this.client.on('failure', function(error) { - winston.info('error connecting to memcached', {error}); - }); - } - - // Save file in a key - set(key, data, callback, skipExpire) { - this.client.set(key, data, skipExpire ? 0 : this.expire || 0, (error) => { - callback(!error); - }); - } - - // Get a file from a key - get(key, callback, skipExpire) { - this.client.get(key, (error, data) => { - const value = error ? false : data; - - callback(value); - - // Update the key so that the expiration is pushed forward - if (value && !skipExpire) { - this.set(key, data, (updateSucceeded) => { - if (!updateSucceeded) { - winston.error('failed to update expiration on GET', {key}); - } - }, skipExpire); - } - }); - } - -} - -module.exports = MemcachedDocumentStore; diff --git a/lib/document_stores/mongo.js b/lib/document_stores/mongo.js deleted file mode 100644 index 502a508..0000000 --- a/lib/document_stores/mongo.js +++ /dev/null @@ -1,88 +0,0 @@ - - -var MongoClient = require('mongodb').MongoClient, - winston = require('winston'); - -var MongoDocumentStore = function (options) { - this.expire = options.expire; - this.connectionUrl = process.env.DATABASE_URl || options.connectionUrl; -}; - -MongoDocumentStore.prototype.set = function (key, data, callback, skipExpire) { - var now = Math.floor(new Date().getTime() / 1000), - that = this; - - this.safeConnect(function (err, db) { - if (err) - return callback(false); - - db.collection('entries').update({ - 'entry_id': key, - $or: [ - { expiration: -1 }, - { expiration: { $gt: now } } - ] - }, { - 'entry_id': key, - 'value': data, - 'expiration': that.expire && !skipExpire ? that.expire + now : -1 - }, { - upsert: true - }, function (err, existing) { - if (err) { - winston.error('error persisting value to mongodb', { error: err }); - return callback(false); - } - - callback(true); - }); - }); -}; - -MongoDocumentStore.prototype.get = function (key, callback, skipExpire) { - var now = Math.floor(new Date().getTime() / 1000), - that = this; - - this.safeConnect(function (err, db) { - if (err) - return callback(false); - - db.collection('entries').findOne({ - 'entry_id': key, - $or: [ - { expiration: -1 }, - { expiration: { $gt: now } } - ] - }, function (err, entry) { - if (err) { - winston.error('error persisting value to mongodb', { error: err }); - return callback(false); - } - - callback(entry === null ? false : entry.value); - - if (entry !== null && entry.expiration !== -1 && that.expire && !skipExpire) { - db.collection('entries').update({ - 'entry_id': key - }, { - $set: { - 'expiration': that.expire + now - } - }, function (err, result) { }); - } - }); - }); -}; - -MongoDocumentStore.prototype.safeConnect = function (callback) { - MongoClient.connect(this.connectionUrl, function (err, db) { - if (err) { - winston.error('error connecting to mongodb', { error: err }); - callback(err); - } else { - callback(undefined, db); - } - }); -}; - -module.exports = MongoDocumentStore; diff --git a/lib/document_stores/postgres.js b/lib/document_stores/postgres.js deleted file mode 100644 index f723dbb..0000000 --- a/lib/document_stores/postgres.js +++ /dev/null @@ -1,80 +0,0 @@ -/*global require,module,process*/ - -var winston = require('winston'); -const {Pool} = require('pg'); - -// create table entries (id serial primary key, key varchar(255) not null, value text not null, expiration int, unique(key)); - -// A postgres document store -var PostgresDocumentStore = function (options) { - this.expireJS = parseInt(options.expire, 10); - - const connectionString = process.env.DATABASE_URL || options.connectionUrl; - this.pool = new Pool({connectionString}); -}; - -PostgresDocumentStore.prototype = { - - // Set a given key - set: function (key, data, callback, skipExpire) { - var now = Math.floor(new Date().getTime() / 1000); - var that = this; - this.safeConnect(function (err, client, done) { - if (err) { return callback(false); } - client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [ - key, - data, - that.expireJS && !skipExpire ? that.expireJS + now : null - ], function (err) { - if (err) { - winston.error('error persisting value to postgres', { error: err }); - return callback(false); - } - callback(true); - done(); - }); - }); - }, - - // Get a given key's data - get: function (key, callback, skipExpire) { - var now = Math.floor(new Date().getTime() / 1000); - var that = this; - this.safeConnect(function (err, client, done) { - if (err) { return callback(false); } - client.query('SELECT id,value,expiration from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now], function (err, result) { - if (err) { - winston.error('error retrieving value from postgres', { error: err }); - return callback(false); - } - callback(result.rows.length ? result.rows[0].value : false); - if (result.rows.length && that.expireJS && !skipExpire) { - client.query('UPDATE entries SET expiration = $1 WHERE ID = $2', [ - that.expireJS + now, - result.rows[0].id - ], function (err) { - if (!err) { - done(); - } - }); - } else { - done(); - } - }); - }); - }, - - // A connection wrapper - safeConnect: function (callback) { - this.pool.connect((error, client, done) => { - if (error) { - winston.error('error connecting to postgres', {error}); - callback(error); - } else { - callback(undefined, client, done); - } - }); - } -}; - -module.exports = PostgresDocumentStore; diff --git a/lib/document_stores/redis.js b/lib/document_stores/redis.js deleted file mode 100644 index eed07e7..0000000 --- a/lib/document_stores/redis.js +++ /dev/null @@ -1,89 +0,0 @@ -var redis = require('redis'); -var winston = require('winston'); - -// For storing in redis -// options[type] = redis -// options[host] - The host to connect to (default localhost) -// options[port] - The port to connect to (default 5379) -// options[db] - The db to use (default 0) -// options[expire] - The time to live for each key set (default never) - -var RedisDocumentStore = function(options, client) { - this.expire = options.expire; - if (client) { - winston.info('using predefined redis client'); - RedisDocumentStore.client = client; - } else if (!RedisDocumentStore.client) { - winston.info('configuring redis'); - RedisDocumentStore.connect(options); - } -}; - -// Create a connection according to config -RedisDocumentStore.connect = function(options) { - var host = options.host || '127.0.0.1'; - var port = options.port || 6379; - var index = options.db || 0; - RedisDocumentStore.client = redis.createClient(port, host); - // authenticate if password is provided - if (options.password) { - RedisDocumentStore.client.auth(options.password); - } - - RedisDocumentStore.client.on('error', function(err) { - winston.error('redis disconnected', err); - }); - - RedisDocumentStore.client.select(index, function(err) { - if (err) { - winston.error( - 'error connecting to redis index ' + index, - { error: err } - ); - process.exit(1); - } - else { - winston.info('connected to redis on ' + host + ':' + port + '/' + index); - } - }); -}; - -// Save file in a key -RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) { - var _this = this; - RedisDocumentStore.client.set(key, data, function(err) { - if (err) { - callback(false); - } - else { - if (!skipExpire) { - _this.setExpiration(key); - } - callback(true); - } - }); -}; - -// Expire a key in expire time if set -RedisDocumentStore.prototype.setExpiration = function(key) { - if (this.expire) { - RedisDocumentStore.client.expire(key, this.expire, function(err) { - if (err) { - winston.error('failed to set expiry on key: ' + key); - } - }); - } -}; - -// Get a file from a key -RedisDocumentStore.prototype.get = function(key, callback, skipExpire) { - var _this = this; - RedisDocumentStore.client.get(key, function(err, reply) { - if (!err && !skipExpire) { - _this.setExpiration(key); - } - callback(err ? false : reply); - }); -}; - -module.exports = RedisDocumentStore; diff --git a/lib/document_stores/rethinkdb.js b/lib/document_stores/rethinkdb.js deleted file mode 100644 index ca825af..0000000 --- a/lib/document_stores/rethinkdb.js +++ /dev/null @@ -1,46 +0,0 @@ -const crypto = require('crypto'); -const rethink = require('rethinkdbdash'); -const winston = require('winston'); - -const md5 = (str) => { - const md5sum = crypto.createHash('md5'); - md5sum.update(str); - return md5sum.digest('hex'); -}; - -class RethinkDBStore { - constructor(options) { - this.client = rethink({ - silent: true, - host: options.host || '127.0.0.1', - port: options.port || 28015, - db: options.db || 'haste', - user: options.user || 'admin', - password: options.password || '' - }); - } - - set(key, data, callback) { - this.client.table('uploads').insert({ id: md5(key), data: data }).run((error) => { - if (error) { - callback(false); - winston.error('failed to insert to table', error); - return; - } - callback(true); - }); - } - - get(key, callback) { - this.client.table('uploads').get(md5(key)).run((error, result) => { - if (error || !result) { - callback(false); - if (error) winston.error('failed to insert to table', error); - return; - } - callback(result.data); - }); - } -} - -module.exports = RethinkDBStore; diff --git a/lib/key_generators/dictionary.js b/lib/key_generators/dictionary.js deleted file mode 100644 index 0bcbc2e..0000000 --- a/lib/key_generators/dictionary.js +++ /dev/null @@ -1,32 +0,0 @@ -const fs = require('fs'); - -module.exports = class DictionaryGenerator { - - constructor(options, readyCallback) { - // Check options format - if (!options) throw Error('No options passed to generator'); - if (!options.path) throw Error('No dictionary path specified in options'); - - // Load dictionary - fs.readFile(options.path, 'utf8', (err, data) => { - if (err) throw err; - - this.dictionary = data.split(/[\n\r]+/); - - if (readyCallback) readyCallback(); - }); - } - - // Generates a dictionary-based key, of keyLength words - createKey(keyLength) { - let text = ''; - - for (let i = 0; i < keyLength; i++) { - const index = Math.floor(Math.random() * this.dictionary.length); - text += this.dictionary[index]; - } - - return text; - } - -}; diff --git a/lib/key_generators/phonetic.js b/lib/key_generators/phonetic.js deleted file mode 100644 index f281f6b..0000000 --- a/lib/key_generators/phonetic.js +++ /dev/null @@ -1,27 +0,0 @@ -// Draws inspiration from pwgen and http://tools.arantius.com/password - -const randOf = (collection) => { - return () => { - return collection[Math.floor(Math.random() * collection.length)]; - }; -}; - -// Helper methods to get an random vowel or consonant -const randVowel = randOf('aeiou'); -const randConsonant = randOf('bcdfghjklmnpqrstvwxyz'); - -module.exports = class PhoneticKeyGenerator { - - // Generate a phonetic key of alternating consonant & vowel - createKey(keyLength) { - let text = ''; - const start = Math.round(Math.random()); - - for (let i = 0; i < keyLength; i++) { - text += (i % 2 == start) ? randConsonant() : randVowel(); - } - - return text; - } - -}; diff --git a/lib/key_generators/random.js b/lib/key_generators/random.js deleted file mode 100644 index 767e26b..0000000 --- a/lib/key_generators/random.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = class RandomKeyGenerator { - - // Initialize a new generator with the given keySpace - constructor(options = {}) { - this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - } - - // Generate a key of the given length - createKey(keyLength) { - var text = ''; - - for (var i = 0; i < keyLength; i++) { - const index = Math.floor(Math.random() * this.keyspace.length); - text += this.keyspace.charAt(index); - } - - return text; - } - -}; diff --git a/server.js b/server.js deleted file mode 100644 index 0837a03..0000000 --- a/server.js +++ /dev/null @@ -1,164 +0,0 @@ -var http = require('http'); -var fs = require('fs'); - -var uglify = require('uglify-js'); -var winston = require('winston'); -var connect = require('connect'); -var route = require('connect-route'); -var connect_st = require('st'); -var connect_rate_limit = require('connect-ratelimit'); - -var DocumentHandler = require('./lib/document_handler'); - -// Load the configuration and set some defaults -const configPath = process.argv.length <= 2 ? 'config.js' : process.argv[2]; -const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); -config.port = process.env.PORT || config.port || 7777; -config.host = process.env.HOST || config.host || 'localhost'; - -// Set up the logger -if (config.logging) { - try { - winston.remove(winston.transports.Console); - } catch(e) { - /* was not present */ - } - - var detail, type; - for (var i = 0; i < config.logging.length; i++) { - detail = config.logging[i]; - type = detail.type; - delete detail.type; - winston.add(winston.transports[type], detail); - } -} - -// build the store from the config on-demand - so that we don't load it -// for statics -if (!config.storage) { - config.storage = { type: 'file' }; -} -if (!config.storage.type) { - config.storage.type = 'file'; -} - -var Store, preferredStore; - -if (process.env.REDISTOGO_URL && config.storage.type === 'redis') { - var redisClient = require('redis-url').connect(process.env.REDISTOGO_URL); - Store = require('./lib/document_stores/redis'); - preferredStore = new Store(config.storage, redisClient); -} -else { - Store = require('./lib/document_stores/' + config.storage.type); - preferredStore = new Store(config.storage); -} - -// Compress the static javascript assets -if (config.recompressStaticAssets) { - var list = fs.readdirSync('./static'); - for (var j = 0; j < list.length; j++) { - var item = list[j]; - if ((item.indexOf('.js') === item.length - 3) && (item.indexOf('.min.js') === -1)) { - var dest = item.substring(0, item.length - 3) + '.min' + item.substring(item.length - 3); - var orig_code = fs.readFileSync('./static/' + item, 'utf8'); - - fs.writeFileSync('./static/' + dest, uglify.minify(orig_code).code, 'utf8'); - winston.info('compressed ' + item + ' into ' + dest); - } - } -} - -// Send the static documents into the preferred store, skipping expirations -var path, data; -for (var name in config.documents) { - path = config.documents[name]; - data = fs.readFileSync(path, 'utf8'); - winston.info('loading static document', { name: name, path: path }); - if (data) { - preferredStore.set(name, data, function(cb) { - winston.debug('loaded static document', { success: cb }); - }, true); - } - else { - winston.warn('failed to load static document', { name: name, path: path }); - } -} - -// Pick up a key generator -var pwOptions = config.keyGenerator || {}; -pwOptions.type = pwOptions.type || 'random'; -var gen = require('./lib/key_generators/' + pwOptions.type); -var keyGenerator = new gen(pwOptions); - -// Configure the document handler -var documentHandler = new DocumentHandler({ - store: preferredStore, - maxLength: config.maxLength, - keyLength: config.keyLength, - keyGenerator: keyGenerator -}); - -var app = connect(); - -// Rate limit all requests -if (config.rateLimits) { - config.rateLimits.end = true; - app.use(connect_rate_limit(config.rateLimits)); -} - -// first look at API calls -app.use(route(function(router) { - // get raw documents - support getting with extension - - router.get('/raw/:id', function(request, response) { - return documentHandler.handleRawGet(request, response, config); - }); - - router.head('/raw/:id', function(request, response) { - return documentHandler.handleRawGet(request, response, config); - }); - - // add documents - - router.post('/documents', function(request, response) { - return documentHandler.handlePost(request, response); - }); - - // get documents - router.get('/documents/:id', function(request, response) { - return documentHandler.handleGet(request, response, config); - }); - - router.head('/documents/:id', function(request, response) { - return documentHandler.handleGet(request, response, config); - }); -})); - -// Otherwise, try to match static files -app.use(connect_st({ - path: __dirname + '/static', - content: { maxAge: config.staticMaxAge }, - passthrough: true, - index: false -})); - -// Then we can loop back - and everything else should be a token, -// so route it back to / -app.use(route(function(router) { - router.get('/:id', function(request, response, next) { - request.sturl = '/'; - next(); - }); -})); - -// And match index -app.use(connect_st({ - path: __dirname + '/static', - content: { maxAge: config.staticMaxAge }, - index: 'index.html' -})); - -http.createServer(app).listen(config.port, config.host); - -winston.info('listening on ' + config.host + ':' + config.port);