From b615ffe4e045581ddd3d016d58c2f57dcd15510f Mon Sep 17 00:00:00 2001 From: Lloyd Brookes Date: Fri, 13 Nov 2015 10:50:59 +0000 Subject: [PATCH] removed --refresh-rate option.. log and test fixes --- bin/ws.js | 3 +- lib/cli-options.js | 4 - lib/local-web-server.js | 39 +++++----- test/static/big-file.txt | 195 +++++++++++++++++++++++++++++++++++++++++++++++ test/test.js | 87 ++++++++++----------- 5 files changed, 262 insertions(+), 66 deletions(-) create mode 100644 test/static/big-file.txt diff --git a/bin/ws.js b/bin/ws.js index 02c7d8a..2a83136 100755 --- a/bin/ws.js +++ b/bin/ws.js @@ -23,7 +23,6 @@ options.stored = loadConfig('local-web-server') options.builtIn = { port: 8000, directory: process.cwd(), - 'refresh-rate': 500, mime: {} } @@ -36,7 +35,7 @@ if (options.cli.misc.config) return console.log(JSON.stringify(options.stored, n localWebServer({ static: { root: options.cli.server.directory }, serveIndex: { path: options.cli.server.directory, options: { icons: true } }, - logger: { format: options.cli.server['log-format'] }, + log: { format: options.cli.server['log-format'] }, compress: options.cli.server.compress }).listen(options.cli.server.port, serverUp) diff --git a/lib/cli-options.js b/lib/cli-options.js index cb37ebd..0cf45bf 100644 --- a/lib/cli-options.js +++ b/lib/cli-options.js @@ -17,10 +17,6 @@ module.exports = { description: 'Enable gzip compression, reduces bandwidth.', group: 'server' }, { - name: 'refresh-rate', alias: 'r', type: Number, - description: 'Statistics view refresh rate in ms. Defaults to 500.', group: 'server' - }, - { name: 'help', alias: 'h', type: Boolean, description: 'Print these usage instructions', group: 'misc' }, diff --git a/lib/local-web-server.js b/lib/local-web-server.js index d8b225d..fc17d07 100644 --- a/lib/local-web-server.js +++ b/lib/local-web-server.js @@ -20,40 +20,38 @@ function getApp (options) { options = Object.assign({ static: {}, serveIndex: {}, - logger: {}, + log: {}, compress: false }, options) + + const log = options.log + log.options = log.options || {} + const app = new Koa() + // app.use((ctx, next) => { + // return next().then(() => ctx.type = 'text/plain') + // }) + if (options.compress) { - console.log('comp'); app.use(convert(compress())) } - - let log = { format: options.logger.format } - if (options.logger.format) { + /* special case log formats */ + if (log.format) { if (log.format === 'none'){ log.format = undefined } else if (log.format === 'logstalgia') { - /* customised logger :date token, purely to satisfy Logstalgia. */ - morgan.token('date', function () { - var d = new Date() - return (d.getDate() + '/' + d.getUTCMonth() + '/' + d.getFullYear() + ':' + d.toTimeString()) - .replace('GMT', '').replace(' (BST)', '') - }) + morgan.token('date', logstalgiaDate) log.format = 'combined' - } else if (log.format) { - log.stream = process.stdout } + /* if no specific log format was requested, show log stats */ } else { log.format = 'common' - log.stream = streamLogStats({ refreshRate: 100 }) + log.options.stream = streamLogStats({ refreshRate: 500 }) } - options.logger.options = options.logger.options || {} - options.logger.options.stream = log.stream - if (log.format) app.use(convert(morgan.middleware(log.format, options.logger.options))) + if (log.format) app.use(convert(morgan.middleware(log.format, log.options))) if (options.static.root) { app.use(convert(serve(options.static.root, options.static.options))) @@ -64,3 +62,10 @@ function getApp (options) { return app } + +function logstalgiaDate () { + var d = new Date() + return (`${d.getDate()}/${d.getUTCMonth()}/${d.getFullYear()}:${d.toTimeString()}`) + .replace('GMT', '') + .replace(' (BST)', '') +} diff --git a/test/static/big-file.txt b/test/static/big-file.txt new file mode 100644 index 0000000..d5b9685 --- /dev/null +++ b/test/static/big-file.txt @@ -0,0 +1,195 @@ +[![view on npm](http://img.shields.io/npm/v/local-web-server.svg)](https://www.npmjs.org/package/local-web-server) +[![npm module downloads per month](http://img.shields.io/npm/dm/local-web-server.svg)](https://www.npmjs.org/package/local-web-server) +[![Dependency Status](https://david-dm.org/75lb/local-web-server.svg)](https://david-dm.org/75lb/local-web-server) +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/feross/standard) + +# local-web-server +Fires up a simple, CORS-enabled, static web server on a given port. Use for local web development or file sharing (directory browsing enabled). + +![local-web-server](http://75lb.github.io/local-web-server/ws.gif) + +## Install +Ensure [node.js](http://nodejs.org) is installed first. Linux/Mac users may need to run the following commands with `sudo`. + +### Globally +```sh +$ npm install -g local-web-server +``` + +### Bundled with your project +```sh +$ npm install local-web-server --save-dev +``` + +Then add an `start` script to your `package.json` (the standard npm approach): +```json +{ + "name": "my-web-app", + "version": "1.0.0", + "scripts": { + "start": "ws" + } +} +``` +This simplifies a rather specific-looking instruction set like: + +```sh +$ npm install +$ npm install -g local-web-server +$ ws +``` + +to the following, server implementation and launch details abstracted away: +```sh +$ npm install +$ npm start +``` + +## Usage +``` +Usage +$ ws +$ ws --config +$ ws --help + +Server +-p, --port Web server port +-f, --log-format If a format is supplied an access log is written to stdout. If not, a statistics view is displayed. Use a + preset ('none', 'dev','combined', 'short', 'tiny' or 'logstalgia') or supply a custom format (e.g. ':method -> + :url'). +-d, --directory Root directory, defaults to the current directory +-c, --compress Enable gzip compression, reduces bandwidth. +-r, --refresh-rate Statistics view refresh rate in ms. Defaults to 500. + +Misc +-h, --help Print these usage instructions +--config Print the stored config +``` + +From the folder you wish to serve, run: +```sh +$ ws +serving at http://localhost:8000 +``` + +If you wish to serve a different directory, run: +```sh +$ ws -d ~/mysite/ +serving /Users/Lloyd/mysite at http://localhost:8000 +``` + +If you wish to override the default port (8000), use `--port` or `-p`: +```sh +$ ws --port 9000 +serving at http://localhost:9000 +``` + +To add compression, reducing bandwidth, increasing page load time (by 10-15% on my Macbook Air) +```sh +$ ws --compress +``` + +### Logging +Passing a value to `--log-format` will write an access log to `stdout`. + +Either use a built-in [morgan](https://github.com/expressjs/morgan) logger preset: +```sh +$ ws --log-format short +``` + +Or a custom [morgan](https://github.com/expressjs/morgan) log format: +```sh +$ ws -f ':method -> :url' +``` + +Or silence: +```sh +$ ws -f none +``` + +## Storing default options +To store per-project options, saving you the hassle of inputting them everytime, store them in the `local-web-server` property of your project's `package.json`: +```json +{ + "name": "my-project", + "version": "0.11.8", + "local-web-server":{ + "port": 8100 + } +} +``` + +Or in a `.local-web-server.json` file stored in the directory you want to serve (typically the root folder of your site): +```json +{ + "port": 8100, + "log-format": "tiny" +} +``` + +Or store global defaults in a `.local-web-server.json` file in your home directory. +```json +{ + "port": 3000, + "refresh-rate": 1000 +} +``` + +All stored defaults are overriden by options supplied at the command line. + +To view your stored defaults, run: + +```sh +$ ws --config +``` + +## mime-types +You can set additional mime-type/extension mappings, or override the defaults by setting a `mime` value in your local config. This value is passed directly to [mime.define()](https://github.com/broofa/node-mime#mimedefine). Example: + +```json +{ + "mime": { + "text/plain": [ "php", "pl" ] + } +} +``` + +## Use with Logstalgia +local-web-server is compatible with [logstalgia](http://code.google.com/p/logstalgia/). + +### Install Logstalgia +On MacOSX, install with [homebrew](http://brew.sh): +```sh +$ brew install logstalgia +``` + +Alternatively, [download a release for your system from github](https://github.com/acaudwell/Logstalgia/releases/latest). + +Then pipe the `logstalgia` output format directly into logstalgia for real-time visualisation: +```sh +$ ws -f logstalgia | logstalgia - +``` + +![local-web-server with logstalgia](http://75lb.github.io/local-web-server/logstagia.gif) + +## Use with glTail +To use with [glTail](http://www.fudgie.org), write your log to disk using the "default" format: +```sh +$ ws -f default > web.log +``` + +Then specify this file in your glTail config: + +```yaml +servers: + dev: + host: localhost + source: local + files: /Users/Lloyd/Documents/MySite/web.log + parser: apache + color: 0.2, 0.2, 1.0, 1.0 +``` + +* * * + +© 2015 Lloyd Brookes <75pound@gmail.com> diff --git a/test/test.js b/test/test.js index 61613f4..23916fb 100644 --- a/test/test.js +++ b/test/test.js @@ -5,9 +5,30 @@ const localWebServer = require('../') const http = require('http') const PassThrough = require('stream').PassThrough +test('log: common', function (t) { + t.plan(1) + const stream = PassThrough() + + stream.on('readable', () => { + let chunk = stream.read() + if (chunk) t.ok(/GET/.test(chunk.toString())) + }) + + const app = localWebServer({ + log: { + format: 'common', + options: { + stream: stream + } + } + }) + launchServer(app) +}) + test('static', function (t) { t.plan(1) const app = localWebServer({ + log: { format: 'none' }, static: { root: __dirname + '/static', options: { @@ -15,18 +36,15 @@ test('static', function (t) { } } }) - const server = http.createServer(app.callback()) - server.listen(8100) - request('http://localhost:8100') - .then(response => { - t.strictEqual(response.data, 'test\n') - }) - .then(() => server.close()) + launchServer(app, null, '/', response => { + t.strictEqual(response.data, 'test\n') + }) }) test('serve-index', function (t) { t.plan(2) const app = localWebServer({ + log: { format: 'none' }, serveIndex: { path: __dirname + '/static', options: { @@ -34,48 +52,31 @@ test('serve-index', function (t) { } } }) - const server = http.createServer(app.callback()) - server.listen(8100) - request('http://localhost:8100/') - .then(response => { - t.ok(/listing directory/.test(response.data)) - t.ok(/class="icon/.test(response.data)) - }) - .then(() => server.close()) + launchServer(app, null, null, response => { + t.ok(/listing directory/.test(response.data)) + t.ok(/class="icon/.test(response.data)) + }) }) -test('log: common', function (t) { +test('compress', function(t){ t.plan(1) - const stream = PassThrough() - - stream.on('readable', () => { - let chunk = stream.read() - if (chunk) t.ok(/GET/.test(chunk.toString())) - }) - const app = localWebServer({ - logger: { - format: 'common', - options: { - stream: stream - } - } + compress: true, + log: { format: 'none' }, + static: { root: __dirname + '/static' } + }) + launchServer(app, { headers: { 'Accept-Encoding': 'gzip' } }, '/big-file.txt', response => { + t.strictEqual(response.res.headers['content-encoding'], 'gzip') }) - const server = http.createServer(app.callback()) - server.listen(8100) - request('http://localhost:8100/') - .then(() => server.close()) -}) - -test('compress', function(t){ - const app = localWebServer({ compress: true }) - }) -function launchServer (app, onSuccess) { +function launchServer (app, reqOptions, path, onSuccess) { + path = `http://localhost:8100${path || '/'}` const server = http.createServer(app.callback()) - server.listen(8100) - const req = request('http://localhost:8100/') - if (onSuccess) req.then(onSuccess) - req.then(() => server.close()) + server.listen(8100, () => { + const req = request(path, reqOptions) + if (onSuccess) req.then(onSuccess) + req.then(() => server.close()) + req.catch(err => console.error('LAUNCH ERROR', err.stack)) + }) }