diff --git a/.gitignore b/.gitignore index 34977ee..0433bbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.idea \ No newline at end of file +.idea +package-lock.json diff --git a/.npmignore b/.npmignore index 737159e..43e5dc2 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,2 @@ .travis.yml -test.js +src/test.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2d5f926 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [2.2.0](https://github.com/Mualig/http-echo-server/compare/v2.1.1...v2.2.0) (2020-12-16) + + +### Features + +* **delay:** added configurable delay ([9f4439d](https://github.com/Mualig/http-echo-server/commit/9f4439d48e6cf2bf07a0742921e0c5746dfa7365)), closes [watson/http-echo-server#5](https://github.com/watson/http-echo-server/issues/5) +* **logs:** added timestamp to logs ([a750f37](https://github.com/Mualig/http-echo-server/commit/a750f378d48151c7c6607090ef52685d0cb86ff0)) diff --git a/README.md b/README.md index 5ea2721..1dd00fc 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ # http-echo-server -Will accept any TCP connection and echo back a HTTP response with the +Forked from [watson/http-echo-server](https://github.com/watson/http-echo-server/) + +Will accept any TCP connection and echo back an HTTP response with the entire content of the incoming TCP connection. The server makes no attempt to understand the incoming HTTP request hence it doesn't know when the request is completed and therefore just terminates the TCP connection 2 seconds after the first data packet. -[![npm](https://img.shields.io/npm/v/http-echo-server.svg)](https://www.npmjs.com/package/http-echo-server) -[![Build status](https://travis-ci.org/watson/http-echo-server.svg?branch=master)](https://travis-ci.org/watson/http-echo-server) -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/standard/standard) ## Installation -To setup a simple echo-server on Heroku just click this button: +To set up a simple echo-server on Heroku just click this button: [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) @@ -27,7 +27,7 @@ versions of npm): npx http-echo-server ``` -Or if you whish to install the module globally: +Or if you wish to install the module globally: ``` npm install http-echo-server -g @@ -65,6 +65,22 @@ export PORT=3005 http-echo-server ``` +## Setting response delay + +To set the response delay (in milliseconds), either supply the port as the 2nd argument to the +`http-echo-server` executable: + +``` +http-echo-server 3005 250 +``` + +Or use the `PORT` environment variable: + +``` +export DELAY=250 +http-echo-server +``` + ## License [MIT](LICENSE) diff --git a/index.js b/index.js deleted file mode 100755 index 408b7f1..0000000 --- a/index.js +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env node -'use strict' - -var getPort = require('get-port') -var server = require('net').createServer() - -var cid = 0 - -module.exports = server // for testing - -onEmit(server, { ignore: ['connection', 'listening', 'error'] }, function (eventName) { - console.log('[server] event:', eventName) -}) - -server.on('connection', function (c) { - var gotData = false - var _cid = ++cid - - console.log('[server] event: connection (socket#%d)', _cid) - - onEmit(c, { ignore: ['lookup', 'error'] }, function (eventName) { - console.log('[socket#%d] event:', _cid, eventName) - }) - - c.on('lookup', function (err, address, family) { - if (err) { - console.log('[socket#%d] event: lookup (error: %s)', _cid, err.message) - } else { - console.log('[socket#%d] event: lookup (address: %s, family: %s)', _cid, address, family) - } - }) - - c.on('data', function (chunk) { - console.log('--> ' + chunk.toString().split('\n').join('\n--> ')) - if (!gotData) { - gotData = true - c.write('HTTP/1.1 200 OK\r\n') - c.write('Date: ' + (new Date()).toString() + '\r\n') - c.write('Connection: close\r\n') - c.write('Content-Type: text/plain\r\n') - c.write('Access-Control-Allow-Origin: *\r\n') - c.write('\r\n') - setTimeout(function () { - c.end() - }, 2000) - } - c.write(chunk.toString()) - }) - - c.on('error', function (err) { - console.log('[socket#%d] event: error (msg: %s)', _cid, err.message) - }) -}) - -server.on('listening', function () { - var port = server.address().port - console.log('[server] event: listening (port: %d)', port) -}) - -server.on('error', function (err) { - console.log('[server] event: error (msg: %s)', err.message) -}) - -var port = process.argv[2] || process.env.PORT - -if (port) { - server.listen(port) -} else { - getPort({ port: 3000 }).then(function (port) { - server.listen(port) - }) -} - -function onEmit (emitter, opts, cb) { - var emitFn = emitter.emit - emitter.emit = function (eventName) { - if (opts.ignore.indexOf(eventName) === -1) cb.apply(null, arguments) - return emitFn.apply(emitter, arguments) - } -} diff --git a/package.json b/package.json index e6226ee..c878a44 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,33 @@ { "name": "http-echo-server", - "version": "2.1.1", + "version": "2.2.0", + "type": "module", "description": "A simple HTTP echo server", - "main": "index.js", - "bin": "index.js", + "main": "src/index.js", + "bin": "src/index.js", "scripts": { - "test": "standard && node test.js", - "start": "node index.js" + "test": "standard && node src/test.js", + "start": "node src/index.js", + "start:dev": "DELAY=250 PORT=3333 npm run start", + "release": "standard-version -s" }, "author": "Thomas Watson Steen ", "license": "MIT", "dependencies": { - "get-port": "^4.0.0" + "get-port": "^7.0.0" }, "devDependencies": { - "standard": "^12.0.1" + "standard": "^17.1.0", + "standard-version": "^9.5.0" }, - "preferGlobal": true, "repository": { "type": "git", - "url": "git+https://github.com/watson/http-echo-server.git" + "url": "git+https://github.com/Mualig/http-echo-server.git" }, "bugs": { - "url": "https://github.com/watson/http-echo-server/issues" + "url": "https://github.com/Mualig/http-echo-server/issues" }, - "homepage": "https://github.com/watson/http-echo-server", + "homepage": "https://github.com/Mualig/http-echo-server", "keywords": [ "http", "tcp", @@ -33,9 +36,5 @@ "debug", "debugger", "test" - ], - "coordinates": [ - 55.778264, - 12.593148 ] } diff --git a/src/index.js b/src/index.js new file mode 100755 index 0000000..6665a8e --- /dev/null +++ b/src/index.js @@ -0,0 +1,87 @@ +#!/usr/bin/env node +'use strict' +import getPort from 'get-port' +import net from 'net' + +let cid = 0 +let timeout = 2000 +export const server = net.createServer() + +onEmit(server, { ignore: ['connection', 'listening', 'error'] }, function (eventName) { + console.log(`[${new Date().toISOString()}][server] event:`, eventName) +}) + +server.on('connection', function (socket) { + let gotData = false + const _cid = ++cid + + console.log(`[${new Date().toISOString()}][server] event: connection (socket#${_cid})`) + + onEmit(socket, { ignore: ['lookup', 'error'] }, function (eventName) { + console.log(`[${new Date().toISOString()}][socket#${_cid}] event:`, eventName) + }) + + socket.on('lookup', function (err, address, family) { + if (err) { + console.log(`[${new Date().toISOString()}][socket#${_cid}] event: lookup (error: ${err.message})`) + } else { + console.log(`[${new Date().toISOString()}][socket#${_cid}] event: lookup (address: ${address}, family: ${family})`) + } + }) + + socket.on('data', function (chunk) { + console.log('--> ' + chunk.toString().split('\n').join('\n--> ')) + if (!gotData) { + gotData = true + socket.write('HTTP/1.1 200 OK\r\n') + socket.write('Date: ' + (new Date()).toString() + '\r\n') + socket.write('Connection: close\r\n') + socket.write('Content-Type: text/plain\r\n') + socket.write('Access-Control-Allow-Origin: *\r\n') + socket.write('\r\n') + setTimeout(function () { + socket.end() + }, timeout) + } + socket.write(chunk.toString()) + }) + + socket.on('error', function (err) { + console.log(`[${new Date().toISOString()}][socket#${_cid}] event: error (msg: ${err.message})`) + }) +}) + +server.on('listening', function () { + const port1 = server.address().port + console.log(`[${new Date().toISOString()}][server] event: listening (port: ${port1})`) +}) + +server.on('error', function (err) { + console.log(`[${new Date().toISOString()}][server] event: error (msg: ${err.message})`) +}) + +const port = process.argv[2] || process.env.PORT + +if (port) { + server.listen(port) +} else { + getPort({ port: 3000 }).then(function (port2) { + server.listen(port2) + }) +} + +const delay = process.argv[3] || process.env.DELAY + +if (delay) { + timeout = delay +} + +console.log(`[${new Date().toISOString()}][server] delay: ${timeout}ms`) + +function onEmit (emitter, opts, cb) { + const emitFn = emitter.emit + emitter.emit = function (eventName) { + if (opts.ignore.indexOf(eventName) === -1) cb.apply(null, arguments) + return emitFn.apply(emitter, arguments) + } +} diff --git a/test.js b/src/test.js similarity index 72% rename from test.js rename to src/test.js index fa9d4a6..f3cd034 100644 --- a/test.js +++ b/src/test.js @@ -1,19 +1,19 @@ 'use strict' -var assert = require('assert') -var net = require('net') +const assert = require('assert') +const net = require('net') -var server = require('./') +const server = require('./index') server.on('listening', function () { - var port = server.address().port - var client = net.createConnection({ port: port }) - var result = '' + const port = server.address().port + const client = net.createConnection({ port: port }) + let result = '' client.on('data', function (chunk) { result += chunk }) client.on('end', function () { - var lines = result.split('\r\n') + const lines = result.split('\r\n') assert.strictEqual(lines.length, 7) assert.strictEqual(lines.shift(), 'HTTP/1.1 200 OK') assert.strictEqual(lines.shift().slice(0, 6), 'Date: ')