Skip to content

Commit

Permalink
Refactors two of the complex functions to be a little simpler
Browse files Browse the repository at this point in the history
Once all of the 6 cyclomatic complexity functions are cleaned up
we'll knock that setting down to 5 and eventually 4. This cleans
up two of them to make them simpler and make the linter happy.

Passes tests.
  • Loading branch information
designfrontier committed Oct 6, 2017
1 parent a27d44d commit 9fa0d78
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 133 deletions.
112 changes: 112 additions & 0 deletions routes/handleStaticFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
'use strict';

const fs = require('fs')
, events = require('harken')
, zlib = require('zlib')
, brotli = require('iltorb')
, mime = require('mime')

, getCompression = require('../utils').getCompression

, not = require('../utils').not
, unmodifiedStatus = 304
, succesStatus = 200

, compressionExtension = (type) => {
if (type === 'br') {
return 'brot';
} else if (type === 'deflate') {
return 'def';
} else {
return 'tgz';
}
}

, getCompressor = (type) => {
if (type === 'br') {
return brotli.compressStream();
} else if (type === 'deflate') {
return zlib.createDeflate();
} else {
return zlib.createGzip();
}
}

, streamFile = (compression, file, connection) => {
const extension = compressionExtension(compression)
, compressor = getCompressor(compression);

fs.stat(`${file}.${extension}`, (err, exists) => {
if (!err && exists.isFile()) {
fs.createReadStream(`${file}.${extension}`).pipe(connection.res);
} else {
// no compressed file yet...
fs.createReadStream(file).pipe(compressor)
.pipe(connection.res);

fs.createReadStream(file).pipe(compressor)
.pipe(fs.createWriteStream(`${file}.${extension}`));
}
});
};

module.exports = (file, connection, config) => {
const req = connection.req
, res = connection.res
, pathname = connection.path.pathname
, compression = getCompression(req.headers['accept-encoding'], config)
, expires = new Date().getTime()
, maxAge = config.maxAge;

fs.stat(file, (err, exists) => {
if (!err && exists.isFile()) {

events.required([ `etag:check:${file}`, `etag:get:${file}` ], (valid) => {
if (valid[0]) { // does the etag match? YES
res.statusCode = unmodifiedStatus;
return res.end();
}
// No match...
res.setHeader('ETag', valid[1]); // the etag is item 2 in the array

if (req.method.toLowerCase() === 'head') {
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
, 'Content-Encoding': compression
});

res.end();
} else if (not(compression === 'none')) {
// we have compression!
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
, 'Content-Encoding': compression
});

streamFile(compression, file, connection);
events.emit('static:served', pathname);
} else {
// no compression carry on...
// return with the correct heders for the file type
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
});
fs.createReadStream(file).pipe(res);
events.emit('static:served', pathname);
}
});

events.emit('etag:check', { file: file, etag: req.headers['if-none-match'] });

} else {
events.emit('static:missing', pathname);
events.emit('error:404', connection);
}
});
};
133 changes: 17 additions & 116 deletions routes/router.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
'use strict';

const path = require('path')
, fs = require('fs')
, zlib = require('zlib')
, events = require('harken')
, mime = require('mime')
, brotli = require('iltorb')
, routeStore = require('./routeStore')
, matchSimpleRoute = require('./matchSimpleRoute')
, isWildCardRoute = require('./isWildCardRoute')
, parseWildCardRoute = require('./parseWildCardRoute')
, setupStaticRoutes = require('./serverSetup')
, setSecurityHeaders = require('../security')
, handleStaticFile = require('./handleStaticFile')

, not = require('../utils').not
, send = require('../utils').send
, setStatus = require('../utils').setStatus
, parsePath = require('../utils').parsePath
, getCompression = require('../utils').getCompression
, redirect = require('../utils').redirect
, contains = require('../utils').contains

, statsd = require('../utils/statsd')

, succesStatus = 200
, unmodifiedStatus = 304;
, succesStatus = 200;

module.exports = (routesJson, config) => {
const publicPath = config.publicPath
, maxAge = config.maxAge
, routePath = config.routePath
, publicFolders = setupStaticRoutes(routePath, publicPath)
, statsdClient = config.statsd === false ? false : statsd.create(config.statsd);
, statsdClient = config.statsd === false ? false : statsd.create(config.statsd)

, setupStatsdListeners = (res, sendStatsd, cleanup) => {
if (statsdClient) {
// Add response listeners
res.once('finish', sendStatsd);
res.once('error', cleanup);
res.once('close', cleanup);
}
};

routeStore.parse(routesJson);

Expand All @@ -41,14 +44,13 @@ module.exports = (routesJson, config) => {
, pathParsed = parsePath(req.url)
, pathname = pathParsed.pathname
, simpleRoute = matchSimpleRoute(pathname, method, routeStore.getStandard())
, expires = new Date().getTime()
, connection = {
req: req
, res: resIn
, query: pathParsed.query
, params: {}
, path: pathParsed
}
, compression = getCompression(req.headers['accept-encoding'], config)
, statsdStartTime = new Date().getTime()

, cleanupStatsd = () => {
Expand Down Expand Up @@ -86,25 +88,18 @@ module.exports = (routesJson, config) => {
cleanupStatsd();
};

let file
, routeInfo
let routeInfo
, res = resIn;

// set up the statsd timing listeners
if (statsdClient) {
// Add response listeners
res.once('finish', sendStatsd);
res.once('error', cleanupStatsd);
res.once('close', cleanupStatsd);
}
// set up the statsd timing listeners
setupStatsdListeners(res, sendStatsd, cleanupStatsd);

// add .setStatus to response
res.setStatus = setStatus;

// add .send to the response
res.send = send(req, config);
res.redirect = redirect(req);

res = setSecurityHeaders(config, req, res);

// match the first part of the url... for public stuff
Expand All @@ -115,101 +110,8 @@ module.exports = (routesJson, config) => {
// the accept-encoding header. So (gzip/deflate/no compression)
res.setHeader('Vary', 'Accept-Encoding');

file = path.join(publicPath, pathname);
// read in the file and stream it to the client
fs.stat(file, (err, exists) => {
if (!err && exists.isFile()) {

events.required([ `etag:check:${file}`, `etag:get:${file}` ], (valid) => {
if (valid[0]) { // does the etag match? YES
res.statusCode = unmodifiedStatus;
return res.end();
}
// No match...
res.setHeader('ETag', valid[1]); // the etag is item 2 in the array

if (req.method.toLowerCase() === 'head') {
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
, 'Content-Encoding': compression
});

res.end();
} else if (not(compression === 'none')) {
// we have compression!
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
, 'Content-Encoding': compression
});

if (compression === 'deflate') {
fs.stat(`${file}.def`, (errDef, existsDef) => {
if (!errDef && existsDef.isFile()) {
fs.createReadStream(`${file}.def`).pipe(res);
} else {
// no compressed file yet...
fs.createReadStream(file).pipe(zlib.createDeflate())
.pipe(res);

fs.createReadStream(file).pipe(zlib.createDeflate())
.pipe(fs.createWriteStream(`${file}.def`));
}
});
} else if (compression === 'br') {
// brotli compression handling
fs.stat(`${file}.brot`, (errBrotli, existsBrotli) => {
if (!errBrotli && existsBrotli.isFile()) {
fs.createReadStream(`${file}.brot`).pipe(res);
} else {
// no compressed file yet...
fs.createReadStream(file).pipe(brotli.compressStream())
.pipe(res);

fs.createReadStream(file).pipe(brotli.compressStream())
.pipe(fs.createWriteStream(`${file}.brot`));
}
});
} else {
fs.stat(`${file}.tgz`, (errTgz, existsTgz) => {
if (!errTgz && existsTgz.isFile()) {
fs.createReadStream(`${file}.tgz`).pipe(res);
} else {
// no compressed file yet...
fs.createReadStream(file).pipe(zlib.createGzip())
.pipe(res);

fs.createReadStream(file).pipe(zlib.createGzip())
.pipe(fs.createWriteStream(`${file}.tgz`));
}
});
}

events.emit('static:served', pathname);

} else {
// no compression carry on...
// return with the correct heders for the file type
res.writeHead(succesStatus, {
'Content-Type': mime.getType(pathname)
, 'Cache-Control': `maxage=${maxAge}`
, Expires: new Date(expires + maxAge).toUTCString()
});
fs.createReadStream(file).pipe(res);
events.emit('static:served', pathname);
}
});

events.emit('etag:check', { file: file, etag: req.headers['if-none-match'] });

} else {
events.emit('static:missing', pathname);
events.emit('error:404', connection);
}
});
handleStaticFile(path.join(publicPath, pathname), connection, config);

} else if (simpleRoute !== null) {
// matches a route in the routes.json
Expand All @@ -225,7 +127,6 @@ module.exports = (routesJson, config) => {
} else if (isWildCardRoute(pathname, method, routeStore.getWildcard())) {
// matches a route in the routes.json file that has params
routeInfo = parseWildCardRoute(pathname, routeStore.getWildcard());

connection.params = routeInfo.values;

// emit the event for the url minus params and include the params
Expand Down
Binary file modified test_stubs/deletes/static/main.js.brot
Binary file not shown.
4 changes: 2 additions & 2 deletions test_stubs/deletes/static/main.js.def
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
x��1
0 �=��[J�FJ��Ф�xw}����cj�T)gġ����1��D<���������cMC��R��JG.
x��1
�=������i�(� &�J�����\ԖT �R�����.g#��g5�&"�&`5�5��!z8r��W���*
Binary file modified test_stubs/deletes/static/main.js.tgz
Binary file not shown.
24 changes: 16 additions & 8 deletions utils/getCompression.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,37 @@ const isDefined = require('./tools').isDefined
return isDefined(config.compress) && !config.compress;
}

, supportsBrotli = (header) => {
, supportsBrotli = (header = '') => {
return header.match(/\bbr\b/) || header.match(/\bbrotli\b/);
}

, supportsGzip = (header) => {
, supportsGzip = (header = '') => {
return header.match(/\bgzip\b/);
}

, supportsDeflate = (header) => {
, supportsDeflate = (header = '') => {
return header.match(/\bdeflate\b/);
}

, getCompression = (header, config) => {
if (isUndefined(header) || dontCompress(config)) {
return 'none';
} else if (supportsBrotli(header)) {
, supportsCompression = (header = '') => {
if (supportsBrotli(header)) {
return 'br';
} else if (supportsGzip(header)) {
return 'gzip';
} else if (supportsDeflate(header)) {
return 'deflate';
} else {
}

return 'none';
}

, getCompression = (header, config) => {
const supported = header ? supportsCompression(header) : 'none';

if (isUndefined(header) || dontCompress(config) || supported === 'none') {
return 'none';
} else {
return supported;
}
};

Expand Down
13 changes: 6 additions & 7 deletions utils/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ const getRawBody = require('raw-body')
connection.req.pipe(busboy);
}

, getCharset = (contentType) => {
return typer.parse(contentType).parameters.charset || 'UTF-8';
}

, parser = (connection, callback, scopeIn) => { // parse out the body
const contentType = connection.req.headers['content-type'] ?
connection.req.headers['content-type'].split(';')[0] : 'application/json'
, scope = scopeIn;

let encoding = 'UTF-8';

if (isDefined(contentType)) {
encoding = typer.parse(contentType).parameters.charset || 'UTF-8';
}
, scope = scopeIn
, encoding = isDefined(contentType) ? getCharset(contentType) : 'UTF-8';

if (contentType === 'multipart/form-data') {
try {
Expand Down

0 comments on commit 9fa0d78

Please sign in to comment.