Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

supporting https #30

Merged
merged 4 commits into from
Jun 27, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

![demo](https://raw.githubusercontent.com/mcollina/autocannon/master/demo.gif)

An HTTP benchmarking tool written in node, greatly inspired by
[wrk][wrk] and [wrk2][wrk2], with support to HTTP pipelining.
A HTTP benchmarking tool written in node, greatly inspired by [wrk][wrk]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably say that this is a HTTP/1.1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

and [wrk2][wrk2], with support for HTTP pipelining and HTTPS.
On _my_ box, *autocannon* can produce more load than `wrk` and `wrk2`.

* [Installation](#install)
Expand Down Expand Up @@ -41,6 +41,8 @@ follow the instructions at [node-gyp][node-gyp].
```
Usage: autocannon [opts] URL

URL is any valid http or https url.

Available options:

-c/--connections NUM The number of concurrent connections to use. default: 10.
Expand Down Expand Up @@ -81,7 +83,7 @@ autocannon({
Start autocannon against the given target.

* `opts`: Configuration options for the autocannon instance. This can have the following attributes. _REQUIRED_.
* `url`: The given target. _REQUIRED_.
* `url`: The given target. Can be http or https. _REQUIRED_.
* `connections`: The number of concurrent connections. _OPTIONAL_ default: `10`.
* `duration`: The number of seconds to run the autocannon. _OPTIONAL_ default: `10`.
* `timeout`: The number of seconds to wait for a response before . _OPTIONAL_ default: `10`.
Expand Down
9 changes: 8 additions & 1 deletion lib/myhttp.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const inherits = require('util').inherits
const EE = require('events').EventEmitter
const net = require('net')
const tls = require('tls')
const retimer = require('retimer')
const HTTPParser = require('http-parser-js').HTTPParser
const methods = [
Expand All @@ -28,6 +29,7 @@ function Client (opts) {

this.opts = opts
this.timeout = (opts.timeout || 10) * 1000
this.secure = opts.protocol === 'https:'
this.parser = new HTTPParser(HTTPParser.RESPONSE)
this.resData = new Array(opts.pipelining)
for (var i = 0; i < this.resData.length; i++) {
Expand Down Expand Up @@ -85,7 +87,12 @@ function Client (opts) {
inherits(Client, EE)

Client.prototype._connect = function () {
this.conn = net.connect(this.opts.port, this.opts.hostname)
if (this.secure) {
this.conn = tls.connect(this.opts.port, this.opts.hostname, { rejectUnauthorized: false })
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow users to specify rejectUnauthorized?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for a load tester it's good to not validate certificates.

} else {
this.conn = net.connect(this.opts.port, this.opts.hostname)
}

this.conn.on('error', () => {
this.emit('connError')
this._connect()
Expand Down
26 changes: 26 additions & 0 deletions test/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEVzCCAz+gAwIBAgIJAJn02lrTTFjxMA0GCSqGSIb3DQEBBQUAMHoxCzAJBgNV
BAYTAklFMRIwEAYDVQQIEwl3YXRlcmZvcmQxDTALBgNVBAcTBHRlc3QxDTALBgNV
BAoTBHRlc3QxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxGzAZBgkqhkiG
9w0BCQEWDHRlc0B0ZXN0LmNvbTAeFw0xNjA2MjcxNDE4MDdaFw0xOTAzMjMxNDE4
MDdaMHoxCzAJBgNVBAYTAklFMRIwEAYDVQQIEwl3YXRlcmZvcmQxDTALBgNVBAcT
BHRlc3QxDTALBgNVBAoTBHRlc3QxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRl
c3QxGzAZBgkqhkiG9w0BCQEWDHRlc0B0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAK0PhkEuPPEQNc1/96rapuEazVaa5p74QAn4PNOPIKaz
XWyLheBF78N320w6jB4eqAe3o6XMtt28iK+q+HejLZt7v+m6c7lHDtfcLSG8CEJ3
dfwR/iOfCLRlDeZyWvxouf9/s3FSAM5VqKb9kmc/Pt2+opWlX1cZvdfkg/lzSHUu
FwmuxOAONKt2dPiEvDSiSs99Kv0+jSgMmy+4D8LGyvxFCQu67bh6a2zGEEYAcAib
Rpw+Fb/AK8VYPW528SaWHRT7CcDgzdXaMfos3EWOQ/Cc0Q+MgqVfSmqTEUPXAc41
Y4Lvvl5GSHQ4lve3jIR05xenxcMIZ8BP7fJ3BfjXCxsCAwEAAaOB3zCB3DAdBgNV
HQ4EFgQUYtl9YCe7XZ4F0MvA627f+BOJoVYwgawGA1UdIwSBpDCBoYAUYtl9YCe7
XZ4F0MvA627f+BOJoVahfqR8MHoxCzAJBgNVBAYTAklFMRIwEAYDVQQIEwl3YXRl
cmZvcmQxDTALBgNVBAcTBHRlc3QxDTALBgNVBAoTBHRlc3QxDTALBgNVBAsTBHRl
c3QxDTALBgNVBAMTBHRlc3QxGzAZBgkqhkiG9w0BCQEWDHRlc0B0ZXN0LmNvbYIJ
AJn02lrTTFjxMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJN7pnlv
SascD2V0I+9wirpuuNnfUP5YCFaAjky4DREV+DRPXEL2tzTQqsEeFts8BHBH+Jz3
ytYP5NZSjuToF9czu8v3+mPCSqzdOFKruJbl/lAokLJWan8Z3qfXWZQL79C2I7Ih
hSBnH/O+jZz9FPRJ2ydR8DB0LdGVKkQFvZynPZOh7D4NKvrEgFad4p6EBFshO+8N
1ALfR/2mrJOkBHfHPVWMmy6DoXWyVijPuLaa+l2TzdQJycl6CAJw6F7tPoO75qKY
MAcIKOW5F9Zv7I3aqmoLDOaOh43FeT2JLvODe2TIaytWckoFesGadEgvAzCAXC4r
ArqQX2nVUdasOnQ=
-----END CERTIFICATE-----
25 changes: 25 additions & 0 deletions test/helper.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
'use strict'

const http = require('http')
const https = require('https')
const fs = require('fs')
const path = require('path')

function startServer () {
const server = http.createServer(handle)
Expand All @@ -26,5 +29,27 @@ function startTimeoutServer () {
return server
}

// this server won't reply to requests
function startHttpsServer () {
const options = {
key: fs.readFileSync(path.join(__dirname, '/key.pem')),
cert: fs.readFileSync(path.join(__dirname, '/cert.pem')),
passphrase: 'test'
}

const server = https.createServer(options, handle)

server.listen(0)

function handle (req, res) {
res.end('hello world')
}

server.unref()

return server
}

module.exports.startServer = startServer
module.exports.startTimeoutServer = startTimeoutServer
module.exports.startHttpsServer = startHttpsServer
30 changes: 30 additions & 0 deletions test/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,081E2A4DFAF06358

yfmHgUwn2RV+CGBYKJMBfLu+EQCKIOprjUxSBPaytTwc6NsOeVjOb/iAcVvr0D6B
a6Kc8BrIMfVVjABghufAnJXav+aB6Q/LkfaqJp6AfVI86WMaCBb0Fzkg8IYYSbgy
JiskTYmV1IrjYfR6TEtQmeFP0DMh1RU9VLIfehEFRMU7LcDh5Ah3bsZE5muBSlws
98IVBwEwEXoQdVxLJmz+kR3fEjXYmgNZQzP6GFb3jQENV3XijQffgQ4ajREB5EZL
Zag+K0vwbFZORqWNfI5VFVVWOEErRF0BSDFZWJP8jbiSX4tNyEFRzO2dgdjGycqt
3dtWbofY28Hjf36P3ee2mMHe3V8XZUtCtfufiYFLKHedHShg7FolfSSMmIfNmSgE
jCnTFNU4Fsq8I/q6ywfVh3CP/rjEe/I4GAU7wql0PW7LXjAHqRjLshJ09mX5J3w8
+tvsrYiBLsgmtdnX47LDJDyeYZY5gbBaz9XsNd432z1M6lRILsT48RYwXEz5oHBE
El1oKNko/PHljDkTph/xI1jUlkYJ7w9//stao/9VLzn0XQG839+lz1MNi/opmpUi
3P9Z3+yTbdwibRHLmgCR6PNE4EJdfv0VNantsxiSATyhIS/xPGhU4lich8gMNDcv
9IcUSCTkmVGy8ksJITt/m7mespQ8Y1oD3xvXoaCbTJ8aig6EQ5flYwmmiIHrWSol
5w5iKjkNbdNYftAg+RB6+EwrNz43oHLYRMB3dckYc1L+otd/X+lmlTlqOo8WDgh1
cH4MI4cwjdYmFdp5Nhfd9/nWFtayqcj59IBgEAMzafbzcmhma6oJD9GsxSnw9eRY
vb3b7fhtcqeKDgqfN4TklX/7kkoLpRVMEdW4uNyU0US1QC5gTxiFRW3/XGhaQJ6o
quE2UP3qySp7kHsz++P6mya2xF2JNcKh1zxxF+wSnjymUxaWXz1LKGQs4iOjU8Xg
HkPD3wTxtMXXZw/0LGMu7XLMFWMV3nuMGtt/I/GGtCbKbFkDOOI4imZWpmsvvO0s
liMhhtCwJTqkYvlxPtfcLSKFJrwcCeb2xHcLEDAaRa5xUbUt3P60l7Ujyv3p+bVi
sItGE6Mk8kGXglmZGBA0RIGhXlX7r6pNryqMUy0CU5/YniJFCKoaU9WOG8VwHynY
psqvZ1umAtl4twe7SxF0znLdOGiYsOOQls5wcz1rDfj5IXRcbrWEeLwYD9b0oXms
TvgkcfHlutZ+M+NtP7wGFBen1X68HsYBhvhLrVbox5bgMZVrXCN4+HiBO4VAwq+m
c2akVF9kQfoR5iGMhzzgskH8c7TWuF7IDqA8KBuFKcicBHK/Ns/1ljycWr07cLJc
WabX25aI0x58+ise5fJAQvNW6Oq2Jvt3qcUXnr2OMnR6WUQ7amgVC7JAdfRoahYU
2WJl6jkCANIv5mY7ubEgVgXnuYYL4ljScpMZLER3cLW4uQnRXWo4zciz06+BadfI
PjGb9xt+3EE4VB64O3yI9yBoDAM/lL0oadB8TPxFLN1NZA3gixbE6dXd5jGD9YxJ
rJNu8xR4MUttiHA8+aVw84kiqsY8OzrjbJnVr2SSXARYw4dnz8DfxhPCt6hMCWnw
-----END RSA PRIVATE KEY-----
18 changes: 18 additions & 0 deletions test/myhttp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const Client = require('../lib/myhttp')
const helper = require('./helper')
const server = helper.startServer()
const timeoutServer = helper.startTimeoutServer()
const httpsServer = helper.startHttpsServer()
const bl = require('bl')

test('client calls a server twice', (t) => {
Expand All @@ -22,6 +23,23 @@ test('client calls a server twice', (t) => {
})
})

test('client calls a https server twice', (t) => {
t.plan(4)

var opts = httpsServer.address()
opts.protocol = 'https:'
const client = new Client(opts)
let count = 0

client.on('response', (statusCode, length) => {
t.equal(statusCode, 200, 'status code matches')
t.ok(length > 'hello world'.length, 'length includes the headers')
if (count++ > 0) {
client.destroy()
}
})
})

test('myhttp client automatically reconnects', (t) => {
t.plan(4)

Expand Down