UNPKG

bot18

Version:

A high-frequency cryptocurrency trading bot by Zenbot creator @carlos8f

416 lines (366 loc) 9.97 kB
var url = require('url') , http = require('http') , utils = require('./utils') , expres = module.exports = {}; expres.middleware = function (req, res, next) { if (!res.req) res.req = req; if (!res.next) res.next = next; Object.keys(expres.methods).forEach( function (method) { // We don't override existing methods. if (typeof res[method] === 'undefined') { res[method] = expres.methods[method].bind(res); } }); if (next) next(); }; expres.methods = { /** * Set status `code`. * * @param {Number} code * @return {ServerResponse} */ status: function(code){ this.statusCode = code; return this; }, /** * Set Link header field with the given `links`. * * Examples: * * res.links({ * next: 'http://api.example.com/users?page=2', * last: 'http://api.example.com/users?page=5' * }); * * @param {Object} links * @return {ServerResponse} */ links: function(links){ return this.set('Link', Object.keys(links).map(function(rel){ return '<' + links[rel] + '>; rel="' + rel + '"'; }).join(', ')); }, /** * Set the Content-Type to `type`. * * Example: * * res.type('application/json'); * * @param {String} type * @return {ServerResponse} for chaining */ type: function(type){ return this.set('Content-Type', type); }, /** * Send a response. * * Examples: * * res.send(new Buffer('wahoo')); * res.send({ some: 'json' }); * res.send('<p>some html</p>'); * res.send(404, 'Sorry, cant find that'); * res.send(404); * * @param {Mixed} body or status * @param {Mixed} body * @return {ServerResponse} */ send: function(body){ var req = this.req , head = 'HEAD' == req.method , len; // allow status / body if (2 == arguments.length) { // res.send(body, status) backwards compat if ('number' != typeof body && 'number' == typeof arguments[1]) { this.statusCode = arguments[1]; } else { this.statusCode = body; body = arguments[1]; } } switch (typeof body) { // response status case 'number': this.get('Content-Type') || this.type('text/plain'); this.statusCode = body; body = http.STATUS_CODES[body]; break; // string defaulting to html case 'string': if (!this.get('Content-Type')) { this.type('text/html; charset=utf-8'); } break; case 'boolean': case 'object': if (null === body) { body = ''; } else if (Buffer.isBuffer(body)) { this.get('Content-Type') || this.type('application/octet-stream'); } else { return this.json(body); } break; } // populate Content-Length if (undefined !== body && !this.get('Content-Length')) { this.set('Content-Length', len = Buffer.isBuffer(body) ? body.length : Buffer.byteLength(body)); } // ETag support // TODO: W/ support // if (len > 1024) { // if (!this.get('ETag')) { // this.set('ETag', etag(body)); // } // } // freshness // if (req.fresh) this.statusCode = 304; // strip irrelevant headers if (204 == this.statusCode || 304 == this.statusCode) { this.removeHeader('Content-Type'); this.removeHeader('Content-Length'); body = ''; } // respond this.end(head ? null : body); return this; }, /** * Send JSON response. * * Examples: * * res.json(null); * res.json({ user: 'tj' }); * res.json(500, 'oh noes!'); * res.json(404, 'I dont have that'); * * @param {Mixed} obj or status * @param {Mixed} obj * @return {ServerResponse} */ json: function(obj){ // allow status / body if (2 == arguments.length) { // res.json(body, status) backwards compat if ('number' == typeof arguments[1]) { this.statusCode = arguments[1]; } else { this.statusCode = obj; obj = arguments[1]; } } var body = JSON.stringify(obj, null, 2); // content-type this.get('Content-Type') || this.set('Content-Type', 'application/json; charset=utf-8'); return this.send(body); }, /** * Send JSON response with JSONP callback support. * * Examples: * * res.jsonp(null); * res.jsonp({ user: 'tj' }); * res.jsonp(500, 'oh noes!'); * res.jsonp(404, 'I dont have that'); * * @param {Mixed} obj or status * @param {Mixed} obj * @return {ServerResponse} */ jsonp: function(obj){ // allow status / body if (2 == arguments.length) { // res.json(body, status) backwards compat if ('number' == typeof arguments[1]) { this.statusCode = arguments[1]; } else { this.statusCode = obj; obj = arguments[1]; } } var body = JSON.stringify(obj, null, 2); if (!this.req.query) { this.req.query = url.parse(this.req.url, true).query; } var callback = this.req.query['callback']; // content-type this.set('Content-Type', 'application/json; charset=utf-8'); // jsonp if (callback) { this.set('Content-Type', 'text/javascript; charset=utf-8'); body = callback.replace(/[^\[\]\w$.]/g, '') + '(' + body + ');'; } return this.send(body); }, /** * Respond to the Acceptable formats using an `obj` * of content-type callbacks. * * Content-Type is set for you, however if you choose * you may alter this within the callback using `res.type()` * or `res.set('Content-Type', ...)`. * * res.format({ * 'text/plain': function(){ * res.send('hey'); * }, * * 'text/html': function(){ * res.send('<p>hey</p>'); * }, * * 'appliation/json': function(){ * res.send({ message: 'hey' }); * } * }); * * By default expres passes an `Error` * with a `.status` of 406 to `next(err)` * if a match is not made. If you provide * a `.default` callback it will be invoked * instead. * * @param {Object} obj * @return {ServerResponse} for chaining */ format: function(obj){ var req = this.req , next = req.next; var fn = obj.default; if (fn) delete obj.default; var keys = Object.keys(obj); var key = utils.accepts(keys, req.headers['Accept'] || req.headers['accept']); this.set('Vary', 'Accept'); if (key) { this.set('Content-Type', utils.normalizeType(key)); obj[key](req, this, next); } else if (fn) { fn(); } else { var err = new Error('Not Acceptable'); err.status = 406; err.types = utils.normalizeTypes(keys); next(err); } return this; }, /** * Set header `field` to `val`, or pass * an object of header fields. * * Examples: * * res.set('Accept', 'application/json'); * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' }); * * Aliased as `res.header()`. * * @param {String|Object} field * @param {String} val * @return {ServerResponse} for chaining */ set: function(field, val){ if (2 == arguments.length) { this.setHeader(field, '' + val); } else { for (var key in field) { this.setHeader(key, '' + field[key]); } } return this; }, /** * Get value for header `field`. * * @param {String} field * @return {String} */ get: function(field){ return this.getHeader(field); }, /** * Redirect to the given `url` with optional response `status` * defaulting to 302. * * The given `url` can also be the name of a mapped url, for * example by default expres supports "back" which redirects * to the _Referrer_ or _Referer_ headers or "/". * * Examples: * * res.redirect('/foo/bar'); * res.redirect('http://example.com'); * res.redirect(301, 'http://example.com'); * res.redirect('http://example.com', 301); * res.redirect('../login'); // /blog/post/1 -> /blog/login * * @param {String} toUrl * @param {Number} code */ redirect: function(toUrl){ var req = this.req , head = 'HEAD' == req.method , status = 302 , body; // allow status / toUrl if (2 == arguments.length) { if ('number' == typeof toUrl) { status = toUrl; toUrl = arguments[1]; } else { status = arguments[1]; } } // setup redirect map var map = { back: req.headers['Referrer'] || '/' }; // perform redirect toUrl = map[toUrl] || toUrl; // relative if (!~toUrl.indexOf('://') && 0 != toUrl.indexOf('//')) { // In express this fetches the app's mount point (root). var path = ''; // relative to path if ('.' == toUrl[0]) { toUrl = url.parse(req.url).path + '/' + toUrl; // relative to root } else if ('/' != toUrl[0]) { toUrl = '/' + toUrl; } // Absolute var host = req.headers['host'] || req.headers['Host']; toUrl = '//' + host + toUrl; } // Support text/{plain,html} by default this.format({ 'text/plain': function(){ body = http.STATUS_CODES[status] + '. Redirecting to ' + toUrl; }, 'text/html': function(){ var u = utils.escape(toUrl); body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'; }, default: function(){ body = ''; } }); // Respond this.status(status); this.set('Location', toUrl); this.set('Content-Length', Buffer.byteLength(body)); this.end(head ? null : body); } }; // Alias for 'type'. expres.methods.contentType = expres.methods.type; // Alias for 'set'. expres.methods.header = expres.methods.set;