Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

echoecho

Package Overview
Dependencies
Maintainers
2
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

echoecho - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5

tests/fixtures/file.json

29

lib/echo.js

@@ -9,3 +9,5 @@ /*

var parse = require('url').parse;
var path = require('path');
var path = require('path');
var fs = require('fs');
var qs = require('querystring');

@@ -80,6 +82,27 @@ /*

serve: function (req, res) {
var base = this.validate(req);
var self = this,
base = this.validate(req),
filepath,
parsed,
query,
data;
if (base && base !== true) {
if (this.scheme[base]) {
this.scheme[base](req, res);
query = parse(req.url).query,
parsed = qs.parse(query);
if (parsed.response) {
this.scheme[base](req, res, parsed.response);
} else if (parsed.file) {
filepath = path.join(__dirname, parsed.file);
fs.readFile(filepath, function (err, data) {
if (err) {
self.scheme.status(404, res);
}
self.scheme[base](req, res, data);
});
} else {
this.scheme[base](req, res, data);
}
} else {

@@ -86,0 +109,0 @@ this.scheme.status(base, res);

85

lib/scheme.js

@@ -16,2 +16,4 @@ /*

var RE_DELAY_RANGE = /(\d+)-(\d+)/;
function mix(reciever, sender) {

@@ -27,2 +29,6 @@ Object.keys(sender).forEach(function (key) {

var rand = exports.rand = function (min, max) {
return Math.random() * (max - min) + min;
};
exports.headers = headers;

@@ -42,19 +48,17 @@

exports.get = function (req, res) {
var p = parse(req.url),
code = ((req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') ? 200 : 403);
exports.get = function (req, res, body) {
var code = ((req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') ? 200 : 403);
res.writeHead(code, headers);
res.end(p.query || '');
res.end(body || parse(req.url).query || '');
};
exports['delete'] = function (req, res) {
var p = parse(req.url),
code = ((req.method === 'DELETE') ? 200 : 403);
exports['delete'] = function (req, res, body) {
var code = ((req.method === 'DELETE') ? 200 : 403);
res.writeHead(code, headers);
res.end(p.query || '');
res.end(body || parse(req.url).query || '');
};
var post = function (method, req, res) {
var post = function (method, req, res, body) {
var data = '',

@@ -67,5 +71,8 @@ gotData = false,

var body = Object.keys(qs.parse(data)).length > 0 ? data : '',
code;
var code;
if (!body) {
body = Object.keys(qs.parse(data)).length > 0 ? data : '';
}
if (req.method === method) {

@@ -84,3 +91,5 @@ code = body ? 200 : 204;

// Check if we have data, and aid Express' `req` object.
if (req.body && Object.keys(req.body).length) {
if (body) {
end();
} else if (req.body && Object.keys(req.body).length) {
data = qs.stringify(req.body);

@@ -109,28 +118,50 @@ gotData = true;

exports.post = function (req, res) {
post('POST', req, res);
exports.post = function (req, res, body) {
post('POST', req, res, body);
};
exports.put = function (req, res) {
post('PUT', req, res);
exports.put = function (req, res, body) {
post('PUT', req, res, body);
};
exports.delay = function (req, res) {
exports.delay = function (req, res, body) {
var path = parse(req.url).pathname,
parts = path.split('/delay/')[1].split('/'),
delay = parts[0],
scheme = parts[1],
range = delay.match(RE_DELAY_RANGE),
seconds;
var delay = parseInt(req.url.split('/').pop(), 10),
seconds = (delay * 1000);
if (range) {
seconds = rand(parseInt(range[1], 10), parseInt(range[2], 10));
} else {
seconds = parseInt(delay, 10) || 0;
}
setTimeout(function () {
res.writeHead(200, headers);
res.end('waited for ' + delay + ' seconds');
}, seconds);
if (scheme && exports[scheme]) {
exports[scheme](req, res, body);
} else {
res.writeHead(200, headers);
res.end('waited for ' + seconds + ' seconds');
}
}, seconds * 1000);
};
exports.json = function (req, res) {
var p = parse(req.url),
json = (p.query ? JSON.stringify(qs.parse(p.query)) : '{ "echo": true }');
exports.json = function (req, res, body) {
var json = body;
if (req.body) {
if (json) {
// Validate.
try {
JSON.parse(json);
} catch (ex) {
return exports.status(400, res);
}
} else if (req.body && Object.keys(req.body).length) {
json = JSON.stringify(req.body);
} else if (parse(req.url).query) {
json = JSON.stringify(qs.parse(parse(req.url).query));
} else {
json = '{ "echo": true }';
}

@@ -137,0 +168,0 @@

@@ -5,3 +5,3 @@ {

"author": "Dav Glass <davglass@gmail.com>",
"version": "0.1.4",
"version": "0.1.5",
"devDependencies": {

@@ -8,0 +8,0 @@ "vows": "*",

@@ -35,2 +35,25 @@ EchoEcho

Delayed Responses
-----------------
You can delay an `echoecho` request with the `delay` route followed by a value
in seconds (e.g., `/delay/3`) or a range in seconds (e.g., `/delay/1-3`). Given
a range, the response will be delayed by a random period of time within the
range.
You can also delay any route by prepending the delay route (e.g.,
`/delay/2/get`, `/delay/1-2/json?response={"hello":"world"}`, etc).
Customized Responses
--------------------
You can customize the response content for any route (except for `status`)
by specifying either a `response` or `file` query parameter.
The `response` query parameter lets you specify the custom response in the URL,
whereas the `file` query parameter will attempt to read a file on the server.
The above ways of specifying custom responses will also work with any delayed
route.
Using in Your Server

@@ -37,0 +60,0 @@ --------------------

@@ -5,3 +5,4 @@ var vows = require('vows'),

parse = require('url').parse,
qs = require('querystring');
qs = require('querystring'),
fs = require('fs'),
echoecho = require('../lib/echo');

@@ -448,2 +449,12 @@

},
'and handle invalid custom json': {
topic: function() {
fetch({
path: '/foo/bar/baz/echo/json?response=invalidJSON'
}, this.callback);
},
'with query body': function(res) {
assert.equal(res.body, 'Bad Request');
}
},
"and post custom json, express style": {

@@ -609,2 +620,29 @@ topic: function() {

},
'and delay by a range of seconds': {
topic: function() {
fetch({
method: 'GET',
path: '/foo/bar/baz/echo/delay/1-3'
}, this.callback);
},
'with query body': function(res) {
var delay = res.body.match(/[\d.]+/);
delay = delay && parseFloat(delay);
assert(delay <= 3, 'delay should be less than 3 seconds');
assert(delay >= 1, 'delay should be more than 1 second');
assert.equal(res.code, 200);
}
},
'and default to 0 for bad delay values': {
topic: function() {
fetch({
method: 'GET',
path: '/foo/bar/baz/echo/delay/delay'
}, this.callback);
},
'with query body': function(res) {
assert.equal(res.code, 200);
assert.equal(res.body, 'waited for 0 seconds');
}
},
'should be instantitable': {

@@ -733,3 +771,126 @@ 'should be different objects': {

// -- Setup for general testing of routes -------------------------------------
var testRoutes = [{
name: 'get',
method: 'GET'
}, {
name: 'post',
method: 'POST'
}, {
name: 'json',
method: 'GET'
}, {
name: 'json',
method: 'POST'
}, {
name: 'put',
method: 'PUT'
}, {
name: 'delete',
method: 'DELETE'
}
];
// -- `response` query parameter tests ----------------------------------------
function assertResponseParam(route, method) {
var json = '{"diaper":"huggies"}';
path = '/foo/bar/baz/echo/' + route + '?response=' + json
context = {
topic: function() {
fetch({
method: method,
path: path
}, this.callback);
}
};
context[route + ' route should use custom response'] = function (res) {
assert.equal(res.body, json);
}
return context;
}
tests['should be loaded']
['and should load paths']
['and should use custom response (query)'] = {};
testRoutes.forEach(function (route) {
tests['should be loaded']
['and should load paths']
['and should use custom response (query)']
['for route ' + route.name + ' with method ' + route.method]
= assertResponseParam(route.name, route.method);
});
// -- `file` query parameter tests --------------------------------------------
var file = fs.readFileSync(__dirname + '/fixtures/file.json', 'utf8');
function assertFileParam(route, method) {
var path = '/foo/bar/baz/echo/' + route + '?file=../tests/fixtures/file.json'
context = {
topic: function() {
fetch({
method: method,
path: path
}, this.callback);
}
};
context[route + ' route should use custom response'] = function (res) {
assert.equal(res.body, file);
}
return context;
}
tests['should be loaded']
['and should load paths']
['and should use custom response (file)'] = {};
testRoutes.forEach(function (route) {
tests['should be loaded']
['and should load paths']
['and should use custom response (file)']
['for route ' + route.name + ' with method ' + route.method]
= assertFileParam(route.name, route.method);
});
// -- delayable routes --------------------------------------------------------
function assertDelayedRoute(route, method) {
var json = '{"megatron":"decepticon","optimus":"autobot"}',
path = '/foo/bar/baz/echo/delay/1/' + route + '?response=' + json,
context = {
topic: function() {
fetch({
method: method,
path: path
}, this.callback);
}
};
context[route + ' route should be delayed'] = function (res) {
assert.equal(res.body, json);
}
return context;
}
tests['should be loaded']
['and should load paths']
['and routes should be delayable'] = {};
testRoutes.forEach(function (route) {
tests['should be loaded']
['and should load paths']
['and routes should be delayable']
['for route ' + route.name + ' with method ' + route.method]
= assertDelayedRoute(route.name, route.method);
});
vows.describe('echoecho').addBatch(tests).export(module);

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc