Skip to content

Commit

Permalink
feat: Add support for specifying connection timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
prantlf committed Mar 10, 2019
1 parent 873c6a3 commit 6edb361
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 24 deletions.
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,22 @@ Usage: nettime [options] <URL>
Options:
-V, --version output the version number
-0, --http1.0 use HTTP 1.0
--http1.1 use HTTP 1.1 (default)
--http2 use HTTP 2.0
-d, --data <data> data to be sent using the POST verb
-f, --format <format> set output format: text, json
-H, --header <header> send specific HTTP header
-i, --include include response headers in the output
-I, --head use HEAD verb to get document info only
-k, --insecure ignore certificate errors
-o, --output <file> write the received data to a file
-t, --time-unit <unit> set time unit: ms, s+ns
-u, --user <credentials> credentials for Basic Authentication
-X, --request <verb> specify HTTP verb to use for the request
-h, --help output usage information
-V, --version output the version number
-0, --http1.0 use HTTP 1.0
--http1.1 use HTTP 1.1 (default)
--http2 use HTTP 2.0
-c, --connect-timeout <ms> maximum time to wait for a connection
-d, --data <data> data to be sent using the POST verb
-f, --format <format> set output format: text, json
-H, --header <header> send specific HTTP header
-i, --include include response headers in the output
-I, --head use HEAD verb to get document info only
-k, --insecure ignore certificate errors
-o, --output <file> write the received data to a file
-t, --time-unit <unit> set time unit: ms, s+ns
-u, --user <credentials> credentials for Basic Authentication
-X, --request <verb> specify HTTP verb to use for the request
-h, --help output usage information
The default output format is "text" and time unit "ms". Other options
are compatible with curl. Timings are printed to the standard output.
Expand Down Expand Up @@ -152,6 +153,7 @@ In lieu of a formal styleguide, take care to maintain the existing coding style.

## Release History

* 2019-03-10 v2.1.0 Added option for setting connection timeout
* 2018-05-19 v2.0.1 Fixed http2 connection for Node.js 8.11.2
* 2018-04-27 v2.0.0 Dropped support of Node.js 4
* 2018-03-16 v1.1.2 Upgrade package dependencies
Expand Down
4 changes: 3 additions & 1 deletion bin/nettime
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ commander.version(pkg.version)
.option('-0, --http1.0', 'use HTTP 1.0')
.option('--http1.1', 'use HTTP 1.1 (default)')
.option('--http2', 'use HTTP 2')
.option('-c, --connect-timeout <ms>', 'maximum time to wait for a connection', parseInt)
.option('-d, --data <data>', 'data to be sent using the POST verb')
.option('-f, --format <format>', 'set output format: text, json')
.option('-H, --header <header>', 'send specific HTTP header', collect, [])
Expand Down Expand Up @@ -86,7 +87,8 @@ nettime({
method: commander.request || (commander.head ? 'HEAD'
: commander.data ? 'POST' : 'GET'),
outputFile: commander.output,
rejectUnauthorized: !commander.insecure
rejectUnauthorized: !commander.insecure,
timeout: commander.connectTimeout
})
.then(function (result) {
const timeUnit = commander.timeUnit
Expand Down
17 changes: 15 additions & 2 deletions lib/nettime.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ function nettime (options) {
const outputFile = options.outputFile
const returnResponse = options.returnResponse
const includeHeaders = options.includeHeaders
var data = (outputFile || returnResponse) && Buffer.from([])
var start, response
let data = (outputFile || returnResponse) && Buffer.from([])
let start
let response

function returnResult () {
const result = {
Expand Down Expand Up @@ -171,6 +172,18 @@ function nettime (options) {
}
}

const timeout = options.timeout
if (timeout) {
request
.on('timeout', () => {
request.abort()
const error = new Error('Connection timed out.')
error.code = 'ETIMEDOUT'
reject(error)
})
.setTimeout(timeout)
}

const inputData = options.data
if (inputData) {
request.write(inputData)
Expand Down
17 changes: 11 additions & 6 deletions tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function makeRequest (protocol, host, port, path, options) {
const https = protocol === 'https'
const url = protocol + '://' + host + ':' + port + (path || '')
let credentials, headers, method, outputFile, failOnOutputFileError
let returnResponse, includeHeaders, data, httpVersion
let returnResponse, includeHeaders, data, httpVersion, timeout
if (options) {
if (options.username) {
credentials = options
Expand All @@ -115,6 +115,8 @@ function makeRequest (protocol, host, port, path, options) {
data = options.data
} else if (options.httpVersion) {
httpVersion = options.httpVersion
} else if (options.timeout) {
timeout = options.timeout
} else {
headers = options
}
Expand All @@ -130,7 +132,8 @@ function makeRequest (protocol, host, port, path, options) {
method: method,
outputFile: outputFile,
rejectUnauthorized: false,
returnResponse: returnResponse
returnResponse: returnResponse,
timeout: timeout
} : url)
.then(checkRequest.bind(null, {
httpVersion: httpVersion,
Expand Down Expand Up @@ -252,12 +255,14 @@ test.test('test with a missing web page', test => {
.then(test.end)
})

test.test('test with an unreachable host', test => {
return makeRequest('http', '127.0.0.0', 80)
test.test('test timed out connection to an unreachable host', test => {
return makeRequest('http', '192.0.2.1', 80, '/', {
timeout: 10
})
.then(test.fail)
.catch(error => {
test.ok(error instanceof Error)
test.equal(error.code, 'ENETUNREACH')
test.equal(error.code, 'ETIMEDOUT')
})
.catch(test.threw)
.then(test.end)
Expand All @@ -278,7 +283,7 @@ test.test('test with custom headers', test => {
return makeRequest('http', ipAddress, unsecurePort, '/download', {
TestHeader: 'Test value'
})
.then(result => {
.then(() => {
const headers = lastRequest.headers
test.ok(headers)
test.equal(Object.keys(headers).length, 3)
Expand Down

0 comments on commit 6edb361

Please sign in to comment.