diff --git a/README.md b/README.md index 42446dc9..13269565 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Start autocannon against the given target. * `method`: The http method to use. _OPTIONAL_ `default: 'GET'`. * `body`: A `String` or a `Buffer` containing the body of the request. Leave undefined for an empty body. _OPTIONAL_ default: `undefined`. * `headers`: An `Object` containing the headers of the request. _OPTIONAL_ default: `{}`. + * `customiseRequest`: A `Function` which will be passed the `Client` object for each connection to be made. This can be used to customise each individual connection headers and body using the API shown below. The changes you make to the client in this function will take precedence over the default `body` and `headers` you pass in here. There is an example of this in the samples folder. _OPTIONAL_ default: `function noop () {}`. * `cb`: The callback which is called on completion of the benchmark. Takes the following params. _OPTIONAL_. * `err`: If there was an error encountered with the run. * `results`: The results of the run. diff --git a/lib/myhttp.js b/lib/myhttp.js index 43c5bb47..e31c129b 100644 --- a/lib/myhttp.js +++ b/lib/myhttp.js @@ -16,6 +16,7 @@ function Client (opts) { return new Client(opts) } + opts.customiseRequest = opts.customiseRequest || noop opts.pipelining = opts.pipelining || 1 opts.port = opts.port || 80 opts.method = opts.method || 'GET' @@ -65,6 +66,8 @@ function Client (opts) { this.setHeaders(opts.headers) + opts.customiseRequest(this) + this._connect() } @@ -148,4 +151,6 @@ Client.prototype._rebuild = function () { } } +function noop () {} + module.exports = Client diff --git a/lib/run.js b/lib/run.js index e3849549..f1c4273f 100644 --- a/lib/run.js +++ b/lib/run.js @@ -63,6 +63,7 @@ function run (opts, cb) { url.method = opts.method url.body = opts.body url.headers = opts.headers + url.customiseRequest = opts.customiseRequest let clients = [] for (let i = 0; i < opts.connections; i++) { diff --git a/samples/customise-individual-connection.js b/samples/customise-individual-connection.js new file mode 100644 index 00000000..a3538b87 --- /dev/null +++ b/samples/customise-individual-connection.js @@ -0,0 +1,33 @@ +'use strict' + +const http = require('http') +const autocannon = require('autocannon') + +const server = http.createServer(handle) + +server.listen(0, startBench) + +function handle (req, res) { + res.end('hello world') +} + +function startBench () { + const url = 'http://localhost:' + server.address().port + + autocannon({ + url: url, + connections: 1000, + duration: 10, + customiseRequest: customiseRequest + }, finishedBench) + + let connection = 0 + + function customiseRequest (client) { + client.setBody('connection number', connection++) + } + + function finishedBench (err, res) { + console.log('finished bench', err, res) + } +} diff --git a/test/myhttp.test.js b/test/myhttp.test.js index c84c9670..3d72ad1f 100644 --- a/test/myhttp.test.js +++ b/test/myhttp.test.js @@ -210,7 +210,7 @@ test('client supports changing the headers and body', (t) => { t.same(client._req, new Buffer(`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\r\n`), - 'header changes updated request') + 'changes updated request') client.destroy() }) @@ -237,6 +237,39 @@ test('client supports changing the headers and body together', (t) => { t.same(client._req, new Buffer(`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\r\n`), - 'header changes updated request') + 'changes updated request') + client.destroy() +}) + +test('client customiseRequest function overwrites the headers and body', (t) => { + t.plan(9) + + const opts = server.address() + opts.body = 'hello world' + opts.method = 'POST' + opts.customiseRequest = (client) => { + t.ok(client.setHeadersAndBody, 'client had setHeadersAndBody method') + t.ok(client.setHeaders, 'client had setHeaders method') + t.ok(client.setBody, 'client had setBody method') + + client.setHeadersAndBody({header: 'modifiedHeader'}, 'modified') + } + + const client = new Client(opts) + + t.same(client.opts.body, 'modified', 'body was changed') + t.notSame(client.opts.body, 'hello world', 'body was changed') + + t.same(client.opts.headers, {'Content-Length': 8, header: 'modifiedHeader'}, 'header was changed') + t.notSame(client.opts.body, {'Content-Length': 11}, 'header was changed') + + t.same(client._req, + new Buffer(`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\r\n`), + 'changes updated request') + + t.notSame(client._req, + new Buffer(`POST / HTTP/1.1\r\nHost: localhost:${server.address().port}\r\nConnection: keep-alive\r\nContent-Length: 11\r\n\r\nhello world\r\n`), + 'changes updated request') + client.destroy() })