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

autocannon

Package Overview
Dependencies
Maintainers
3
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

autocannon - npm Package Compare versions

Comparing version 5.0.1 to 5.1.0

lib/url.js

44

autocannon.js

@@ -18,2 +18,3 @@ #! /usr/bin/env node

const track = require('./lib/progressTracker')
const { checkURL, ofURL } = require('./lib/url')

@@ -83,3 +84,3 @@ if (typeof URL !== 'function') {

argv.url = argv._[0]
argv.url = argv._.length > 1 ? argv._ : argv._[0]

@@ -102,3 +103,3 @@ if (argv.onPort) {

if (!argv.url || argv.help) {
if (!checkURL(argv.url) || argv.help) {
console.error(help)

@@ -112,24 +113,29 @@ return

if (process.env.PORT) {
argv.url = new URL(argv.url, `http://localhost:${process.env.PORT}`).href
argv.url = ofURL(argv.url).map(url => new URL(url, `http://localhost:${process.env.PORT}`).href)
}
// Add http:// if it's not there and this is not a /path
if (argv.url.indexOf('http') !== 0 && argv.url[0] !== '/') {
argv.url = `http://${argv.url}`
}
argv.url = ofURL(argv.url).map(url => {
if (url.indexOf('http') !== 0 && url[0] !== '/') {
url = `http://${url}`
}
return url
})
// check that the URL is valid.
try {
// If --on-port is given, it's acceptable to not have a hostname
if (argv.onPort) {
new URL(argv.url, 'http://localhost') // eslint-disable-line no-new
} else {
new URL(argv.url) // eslint-disable-line no-new
ofURL(argv.url).map(url => {
try {
// If --on-port is given, it's acceptable to not have a hostname
if (argv.onPort) {
new URL(url, 'http://localhost') // eslint-disable-line no-new
} else {
new URL(url) // eslint-disable-line no-new
}
} catch (err) {
console.error(err.message)
console.error('')
console.error('When targeting a path without a hostname, the PORT environment variable must be available.')
console.error('Use a full URL or set the PORT variable.')
process.exit(1)
}
} catch (err) {
console.error(err.message)
console.error('')
console.error('When targeting a path without a hostname, the PORT environment variable must be available.')
console.error('Use a full URL or set the PORT variable.')
process.exit(1)
}
})

@@ -136,0 +142,0 @@ if (argv.input) {

@@ -29,3 +29,3 @@ 'use strict'

// only builds if it has dynamic setup
if (typeof this.currentRequest.setupRequest === 'function') {
if (this.reqDefaults.idReplacement || typeof this.currentRequest.setupRequest === 'function') {
this.rebuildRequest()

@@ -32,0 +32,0 @@ }

@@ -12,2 +12,3 @@ 'use strict'

const reInterval = require('reinterval')
const { ofURL, checkURL } = require('./url')
const histAsObj = histUtil.histAsObj

@@ -83,5 +84,2 @@ const addPercentiles = histUtil.addPercentiles

if (opts.url.indexOf('http') !== 0) opts.url = 'http://' + opts.url
const url = URL.parse(opts.url) // eslint-disable-line node/no-deprecated-api
if (opts.overallRate && (opts.overallRate < opts.connections)) opts.connections = opts.overallRate

@@ -114,19 +112,31 @@

// copy over fields so that the client
// performs the right HTTP requests
url.pipelining = opts.pipelining
url.method = opts.method
url.body = form ? form.getBuffer() : opts.body
url.headers = form ? Object.assign({}, opts.headers, form.getHeaders()) : opts.headers
url.setupClient = opts.setupClient
url.timeout = opts.timeout
url.requests = opts.requests
url.reconnectRate = opts.reconnectRate
url.responseMax = amount || opts.maxConnectionRequests || opts.maxOverallRequests
url.rate = opts.connectionRate || opts.overallRate
url.idReplacement = opts.idReplacement
url.socketPath = opts.socketPath
url.servername = opts.servername
url.expectBody = opts.expectBody
opts.url = ofURL(opts.url).map((url) => {
if (url.indexOf('http') !== 0) return 'http://' + url
return url
})
const urls = ofURL(opts.url, true).map(url => {
if (url.indexOf('http') !== 0) url = 'http://' + url
url = URL.parse(url) // eslint-disable-line node/no-deprecated-api
// copy over fields so that the client
// performs the right HTTP requests
url.pipelining = opts.pipelining
url.method = opts.method
url.body = form ? form.getBuffer() : opts.body
url.headers = form ? Object.assign({}, opts.headers, form.getHeaders()) : opts.headers
url.setupClient = opts.setupClient
url.timeout = opts.timeout
url.requests = opts.requests
url.reconnectRate = opts.reconnectRate
url.responseMax = amount || opts.maxConnectionRequests || opts.maxOverallRequests
url.rate = opts.connectionRate || opts.overallRate
url.idReplacement = opts.idReplacement
url.socketPath = opts.socketPath
url.servername = opts.servername
url.expectBody = opts.expectBody
return url
})
let clients = []

@@ -223,2 +233,3 @@ initialiseClients(clients)

for (let i = 0; i < opts.connections; i++) {
const url = urls[i % urls.length]
if (!amount && !opts.maxConnectionRequests && opts.maxOverallRequests) {

@@ -306,3 +317,3 @@ url.responseMax = distributeNums(opts.maxOverallRequests, i)

function checkOptsForErrors () {
if (!opts.url && !opts.socketPath) {
if (!checkURL(opts.url) && !opts.socketPath) {
errorCb(new Error('url or socketPath option required'))

@@ -309,0 +320,0 @@ return true

{
"name": "autocannon",
"version": "5.0.1",
"version": "5.1.0",
"description": "Fast HTTP benchmarking tool written in Node.js",

@@ -5,0 +5,0 @@ "main": "autocannon.js",

@@ -150,1 +150,12 @@ 'use strict'

})
test('parse argument with multiple url', (t) => {
t.plan(2)
var args = Autocannon.parseArguments([
'localhost/foo/bar',
'http://localhost/baz/qux'
])
t.equal(args.url[0], 'http://localhost/foo/bar')
t.equal(args.url[1], 'http://localhost/baz/qux')
})

@@ -15,2 +15,19 @@ 'use strict'

const makeResponseFromBody = ({ server, method, body, headers = {} }) => {
const sentHeaders = {
Connection: 'keep-alive',
...headers
}
if (!sentHeaders['Content-Length'] && body) {
sentHeaders['Content-Length'] = body.length
}
return `${method} / HTTP/1.1\r\nHost: localhost:${
server.address().port
}\r\n${
Object.keys(sentHeaders).map(name => `${name}: ${sentHeaders[name]}`).join('\r\n')
}\r\n${
body ? `\r\n${body}` : '\r\n'
}`
}
test('client calls a server twice', (t) => {

@@ -270,11 +287,8 @@ t.plan(4)

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setBody('modified')
const body = 'modified'
client.setBody(body)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 8\r\n\r\nmodified`),
'body changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts, body }), 'body changes updated request')
client.destroy()

@@ -290,13 +304,8 @@ })

const client = new Client(opts)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\n\r\n`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setHeaders({
header: 'modified'
})
const headers = { header: 'modified' }
client.setHeaders(headers)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nheader: modified\r\n\r\n`),
'header changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts, headers }), 'header changes updated request')
client.destroy()

@@ -314,14 +323,10 @@ })

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setBody('modified')
client.setHeaders({
header: 'modifiedHeader'
})
const body = 'modified'
const headers = { header: 'modifiedHeader' }
client.setBody(body)
client.setHeaders(headers)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nheader: modifiedHeader\r\nContent-Length: 8\r\n\r\nmodified`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts, headers, body }), 'changes updated request')
client.destroy()

@@ -339,13 +344,9 @@ })

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setHeadersAndBody({
header: 'modifiedHeader'
}, 'modified')
const body = 'modified'
const headers = { header: 'modifiedHeader' }
client.setHeadersAndBody(headers, body)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nheader: modifiedHeader\r\nContent-Length: 8\r\n\r\nmodified`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts, headers, body }), 'changes updated request')
client.destroy()

@@ -363,5 +364,3 @@ })

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')

@@ -371,5 +370,3 @@ client.setBody(null)

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\n\r\n`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'POST' }), 'changes updated request')
client.destroy()

@@ -387,11 +384,7 @@ })

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setHeadersAndBody(null, null)
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\n\r\n`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'POST' }), 'changes updated request')
client.destroy()

@@ -409,7 +402,5 @@ })

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'request is okay before modifying')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'request is okay before modifying')
client.setRequest({
const newReq = {
headers: {

@@ -420,7 +411,6 @@ header: 'modifiedHeader'

method: 'GET'
})
}
client.setRequest(newReq)
t.same(client.getRequestBuffer(),
Buffer.from(`GET / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nheader: modifiedHeader\r\nContent-Length: 8\r\n\r\nmodified`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...newReq }), 'changes updated request')
client.destroy()

@@ -435,2 +425,4 @@ })

opts.method = 'POST'
const body = 'modified'
const headers = { header: 'modifiedHeader' }
opts.setupClient = (client) => {

@@ -441,5 +433,3 @@ t.ok(client.setHeadersAndBody, 'client had setHeadersAndBody method')

client.setHeadersAndBody({
header: 'modifiedHeader'
}, 'modified')
client.setHeadersAndBody(headers, body)
}

@@ -449,9 +439,5 @@

t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nheader: modifiedHeader\r\nContent-Length: 8\r\n\r\nmodified`),
'changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts, headers, body }), 'changes updated request')
t.notSame(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'changes updated request')
t.notSame(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts }), 'changes updated request')

@@ -517,6 +503,6 @@ client.destroy()

const opts = server.address()
opts.method = 'POST'
const requests = [
{
method: 'POST',
body: 'hello world again'

@@ -538,10 +524,6 @@ },

case 3:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 17\r\n\r\nhello world again`),
'request was okay')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...requests[0] }), 'request was okay')
break
case 2:
t.same(client.getRequestBuffer(),
Buffer.from(`GET / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 8\r\n\r\nmodified`),
'body changes updated request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...requests[1] }), 'body changes updated request')
break

@@ -561,5 +543,5 @@ case 4:

const opts = server.address()
opts.method = 'POST'
opts.requests = [
{
method: 'POST',
body: 'hello world!',

@@ -569,2 +551,3 @@ onResponse: (status, body) => responses.push({ status, body })

{
method: 'POST',
body: 'hello world again'

@@ -585,5 +568,3 @@ },

case 1:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 12\r\n\r\nhello world!`),
'first request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts.requests[0] }), 'first request')
t.deepEqual(responses, [{

@@ -595,5 +576,3 @@ status: 200,

case 2:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 17\r\n\r\nhello world again`),
'second request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts.requests[1] }), 'second request')
t.deepEqual(responses, [{

@@ -605,5 +584,3 @@ status: 200,

case 3:
t.same(client.getRequestBuffer(),
Buffer.from(`GET / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\n\r\n`),
'third request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts.requests[2] }), 'third request')
t.deepEqual(responses, [{

@@ -618,5 +595,3 @@ status: 200,

case 4:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 12\r\n\r\nhello world!`),
'first request')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts.requests[0] }), 'first request')
t.deepEqual(responses, [{

@@ -642,7 +617,8 @@ status: 200,

const opts = server.address()
opts.method = 'POST'
let number = 0
const expectedResponse = 'hello world'
opts.requests = [
{
method: 'POST',
body: 'hello world again',

@@ -657,5 +633,6 @@ onResponse: (status, body, context) => {

{
method: 'PUT',
setupRequest: (req, context) => {
if (number < 3) {
t.deepEqual(context, { previousRes: 'hello world' }, 'context was supposed to contain previous response')
t.deepEqual(context, { previousRes: expectedResponse }, 'context was supposed to contain previous response')
}

@@ -672,10 +649,6 @@ return Object.assign({}, req, { body: context.previousRes })

case 1:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 17\r\n\r\nhello world again`),
'hard-coded body')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, ...opts.requests[0] }), 'hard-coded body')
break
case 2:
t.same(client.getRequestBuffer(),
Buffer.from(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world`),
'dynamic body')
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'PUT', body: expectedResponse }), 'dynamic body')
client.destroy()

@@ -740,1 +713,81 @@ t.end()

})
test('client emits mistmatch when expectBody doesn\'t match actual body', (t) => {
const responses = ['hello...', 'world!']
const server = helper.startServer({
body: ({ method }) => responses[method === 'POST' ? 0 : 1]
})
const opts = server.address()
opts.requests = [
{
method: 'POST',
body: 'hi there!'
},
{
method: 'GET'
}
]
opts.expectBody = responses[0]
const client = new Client(opts)
client.on('mismatch', (body) => {
// we expect body mismatch on second request
t.same(body, responses[1])
client.destroy()
t.end()
})
})
test('client invokes appropriate onResponse when using pipelining', (t) => {
const server = helper.startServer({
body: ({ method }) => method
})
const opts = server.address()
opts.pipelining = 2
const responses = []
const onResponse = (status, body) => responses.push(body)
opts.requests = [
{
method: 'POST',
onResponse
},
{
method: 'GET',
onResponse
},
{
method: 'PUT',
onResponse
}
]
const client = new Client(opts)
let number = 0
client.on('response', (statusCode, length) => {
number++
switch (number) {
case 1:
// 1st & 2nd were sent, receiving 1st
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'GET' }), 'current should be second request')
t.deepEqual(responses, ['POST'])
break
case 2:
// 3rd was sent as 1st is finished, receiving 2st
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'PUT' }), 'current should be third request')
t.deepEqual(responses, ['POST', 'GET'])
break
case 3:
// 1st was resent, receiving 3st
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'POST' }), 'current should be first request')
t.deepEqual(responses, ['POST', 'GET', 'PUT'])
break
case 4:
// 2st was resent, receiving 1st
t.same(client.getRequestBuffer().toString(), makeResponseFromBody({ server, method: 'GET' }), 'current should be second request')
t.deepEqual(responses, ['POST', 'GET', 'PUT', 'POST'])
client.destroy()
t.end()
break
}
})
})

@@ -176,3 +176,3 @@ 'use strict'

test('request iterator should replace all [<id>] tags with generated IDs when calling move with idReplacement enabled', (t) => {
t.plan(2)
t.plan(4)

@@ -186,6 +186,12 @@ const opts = server.address()

const iterator = new RequestIterator(opts)
const result = iterator.currentRequest.requestBuffer.toString().trim()
const first = iterator.currentRequest.requestBuffer.toString().trim()
t.equal(result.includes('[<id>]'), false, 'One or more [<id>] tags were not replaced')
t.equal(result.slice(-1), '0', 'Generated ID should end with request number')
t.equal(first.includes('[<id>]'), false, 'One or more [<id>] tags were not replaced')
t.equal(first.slice(-1), '0', 'Generated ID should end with request number')
iterator.nextRequest()
const second = iterator.currentRequest.requestBuffer.toString().trim()
t.equal(second.includes('[<id>]'), false, 'One or more [<id>] tags were not replaced')
t.equal(second.slice(-1), '1', 'Generated ID should end with a unique request number')
})

@@ -192,0 +198,0 @@

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