
Security News
Risky Biz Podcast: Making Reachability Analysis Work in Real-World Codebases
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
A minimal REST server that deals solely with JSON payloads that automatically handles CORS requests and limits the size of a POST bodies.
npm install -S take-five
const Five = require('take-five')
const five = new Five()
five.get('/', async (req, res, ctx) => ctx.send('Hello, world'))
five.post('/', async (req, res, ctx) => ctx.send(req.body))
five.listen(3000)
curl -X GET localhost:3000
Hello, world
curl -X POST localhost:3000 -H 'content-type: application/json' -d '{"hello": "world"}'
{"hello": "world"}
In lieu of pre-set middleware, routes handlers can be arrays of functions that will
be iterated over asynchronously. To simplify handling of these handlers,
it is expected that the handlers will return thenables, or terminate the response
stream. This means any promises library should work (including the built in one),
as well as using the async
function keyword.
If you do not return a thenable, handler processing will stop in that function
e.g.:
function badSetContentHeader (req, res, ctx) {
res.setHeader('x-no-way', 'this is gonna do nothing')
}
function goodSetContentHeader (req, res, ctx) {
return new Promise((resolve) => {
res.setHeader('x-yes-way', 'this is gonna do everything!')
resolve()
})
}
function sendReply (req, res, ctx) {
ctx.send('beep!')
}
five.get('/nope', [badSetContentHeader, sendReply])
five.get('/yup', [goodSetContentHeader, sendReply)
since badSetContentHeader
doesn't return a thenable
, take-five will not
know that it needs to call the sendReply
function in the handler list for the /nope
route.
If you have either closed the response stream, or reject
ed the thenable returned
from your route handler, the next route will not be called. In the case that you have
reject
ed the thenable, the error handler will be invoked as well. If you have
closed the response stream, the server assumes you were done processing the request
and will just ignore the remaning functions in the queue.
By default, get
, post
, put
, delete
, options
and patch
will be available
for routing, but this can be changed by providing an array of methods on the options
hash when instatiating a new TakeFive prototype.
five.handleError = (err, req, res, ctx) => {
ctx.err(err.statusCode, err.message)
}
five.get('/:secretdata', [
async (req, res, ctx) => {
try {
const session = await isAuthorized(req.headers.Authorization)
ctx.session = session
} catch (err) {
err.statusCode = 401
throw err
}
},
async (res, res, ctx) => {
try {
const data = await getResource(ctx.params.secretdata, ctx.session)
ctx.send(data)
} catch (err) {
err.statusCode = 500
reject(err)
}
}
])
five.get('/:secretdata', [
(req, res, ctx) => {
return new Promise((resolve, reject) => {
isAuthorized(req.headers.Authorization, (err, session) => {
if (err) {
ctx.err(401, 'Not Authorized')
return reject(new Error('Not authorized'))
}
ctx.session = session
resolve()
})
})
},
(res, res, ctx) => {
return new Promise((resolve, reject) => {
getResource(ctx.params.secretdata, ctx.session, (err, data) => {
if (err) {
ctx.err(500, 'Server error')
return reject(new Error('server error'))
}
ctx.send(data)
resolve()
})
})
}
])
Five(opts?:object):object
Create and return a new HTTP server object.
opts.maxPost?:number
: the max size for a payload. Default: 512kbopts.allowHeaders?:array(string)
: an array of headers to accept besides the default. Default: Content-Type
, Accept
, X-Requested-With
opts.allowOrigin?:string
: What origin(s) are accepted. Deafult: *
opts.allowCredentials?:boolean
: Allow or deny credentials. Default: true
opts.allowContentTypes?:string|string[]
: What content types are allowed to be used when sending data to the server. Default: ['application/json']
. Note: This is additive, so application/json
will ALWAYS be allowed.opts.allowMethods?array(string)
: an array of methods to accept besides the default. Default: PUT
, POST
, DELETE
, GET
, OPTIONS
, PATCH
opts.methods?array(string)
: An array of methods to create route handlers for. Default: PUT
, POST
, DELETE
, GET
, OPTIONS
, PATCH
opts.http?object
: options for http(s).createServer
. If you supply key
,
cert
and ca
as options, it will assume you are trying to create an https server`Access-Control-Allow-Headers
and Access-Control-Allow-Methods
can also be changed during runtime
by setting allowHeaders
and allowMethods
respectively.
Five#get(route:string, handler:(function|array(function)), routeOpts?:object)
Five#post(route:string, handler:(function|array(function)), routeOpts?:object)
Five#put(route:string, handler:(function|array(function)), routeOpts?:object)
Five#patch(route:string, handler:(function|array(function)), routeOpts?:object)
Five#delete(route:string, handler:(function|array(function)), routeOpts?:object)
Five#options(route:string, handler:(function|array(function)), routeOpts?:object)
Add a new route to the server. Routes may be added after the server has been started. You can supply either a single function or an array of functions to call. The array will be traversed in the order it is supplied
route:string
A wayfarer route definition.handler(request:object, response:object, ctx:object):function
: The handler for this route.routeOpts?:object
- overrides for this specific chain of handlers
maxPost:number
- set the maximum size of a payload for this set of handlersallowedContentTypes:string|string[]
- add new allowable content-types for this set of handlersctx:object
query?:object
: query parameters from the URL (if any)params?:object
: Named parameters from the route definition as provided by wayfarerbody?:object
: The parsed JSON body available on POST requestssend(statusCode?:number, body?:(string|object)):function
: Send a response.err(statusCode?:number, message?:string):function
: Send an error. If no status code is provided it will default to a 500 error. If no message is provided, it will use the default message for that status code. The message will be wrapped in a JSON object under the key message
next():function
: Go to the next handlerThe ctx
object can also be extended to contain user defined objects, through
setting this.ctx
to an object. The object will be copied over using Object.assign
.
The keys from above will overwrite any keys you provide named the same.
Five#handleError(err:Error, req:Request, res:Response, ctx:Context)
This function is invoked when either an error object is passed to the ctx.next
method, or the then
-able function's reject
handler is invoked.
This is a no-op by default, allowing you to customize it's behavior.
Five#listen(port:number, handle?:function)
Start listening for requests and call the optional callback when you've started listening
Five.addParser(type:string, parser:functon):void
Add a new content parser to the parsers list. By default there is only a single
parser (application/json
: JSON.parser). This can be overridden with a custom
JSON parser if you'd like.
Five#close()
Shutdown the underlying server
Five.server
The underlying http(s) server from node can be accessed directly. This is non-writeable
Five.maxPost
Globally control the maximum payload size after creation
Five.allowContentTypes
Add new allowable content types for clients to send data with. You can use either an array of strings or a string
Five.allowHeaders
Set a new allowable header or headers for CORS requests. You can use either an array of strings or a string.
Five.allowMethods
Set a new allowable method for CORS requests.
Five.ctx
Add new keys to the ctx objects
Probably not, but restify
, hapi
and express
are all over-kill on the types of services I'm building for the most part.
application/json
payloads, but you can easily extend it toapplication/json
as well, but allow it be override-able if neededI found that the other three projects aim to support way more than this, which means supporting these features involves jumping through hoops or installing a ton of various other packages.
Copyright © 2018 Scripto LLC, Todd Kennedy. Reuse permitted under the Apache-2.0 license
FAQs
Very minimal JSON-REST server
The npm package take-five receives a total of 28 weekly downloads. As such, take-five popularity was classified as not popular.
We found that take-five demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.