Skip to content

Commit

Permalink
feat: Support specifying HTTP version 1.0 in the request header
Browse files Browse the repository at this point in the history
Node.js HTTP support is hard-coded for 1.1. There can be a difference on
the server side only.
  • Loading branch information
prantlf committed Nov 11, 2017
1 parent 33d2917 commit 3cb303c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Usage: nettime [options] <URL>
Options:
-V, --version output the version number
-0, --http1.0 use HTTP 1.0
--http1.1 use HTTP 1.1
-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
Expand All @@ -55,7 +57,7 @@ Options:
-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.
are compatible with curl. Timings are printed to the standard output.
```

## Programmatic usage
Expand All @@ -72,8 +74,7 @@ nettime('https://www.google.com').then(result => {
if (result.statusCode === 200) {
let timings = result.timings
let waiting = nettime.getDuration([0, 0], timings.firstByte)
let downloading = nettime.getDuration(timings.firstByte,
timings.contentTransfer)
let downloading = nettime.getDuration(timings.firstByte, timings.contentTransfer)
console.log('Waiting for the response:', nettime.getMilliseconds(waiting) + 'ms')
console.log('Downloading the content:', nettime.getMilliseconds(downloading) + 'ms')
}
Expand All @@ -90,10 +91,12 @@ The input object can contain:
* `credentials`: object with `username` and `password` string properties to be used for formatting of the Basic Authentication HTTP header.
* `data`: string or Buffer to send to the server using the HTTP verb `POST` and the content type `application/x-www-form-urlencoded` by default.
* `headers`: object with header names as string keys and header values as string values.
* `httpVersion`: string with the protocol version ('1.0' or '1.1') to be sent to the server. (Node.js HTTP support is hard-coded for 1.1. There can be a difference on the server side only.)
* `includeHeaders`: boolean for including property `headers` (`Object`) with response headers in the promised result object. It does not work alone; it extends the output of `returnResponse` or `outputFile`.
* `method`: HTTP verb to use in the HTTP request; `GET` is the default, unless `-i` or `-d` options are not set.
* `outputFile`: file path to write the received data to.
* `rejectUnauthorized`: boolean to refuse finishing the HTTPS request, is set to `true` (the default), if validation of the web site certificate fails; setting it to `false` makes the request ignore certificate errors.
* `returnResponse`: includes property `response` (`Buffer`) with the received data in the promised result object.
* `returnResponse`: boolean for including property `response` (`Buffer`) with the received data in the promised result object.

The result object contains:

Expand Down
12 changes: 8 additions & 4 deletions bin/nettime
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function collect (value, result) {
commander.version(pkg.version)
.description(pkg.description)
.usage('[options] <URL>')
.option('-0, --http1.0', 'use HTTP 1.0')
.option('--http1.1', 'use HTTP 1.1')
.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 @@ -47,7 +49,8 @@ if (!url) {
const headers = commander.header.reduce(function (result, header) {
const colon = header.indexOf(':')
if (colon > 0) {
result[header.substr(0, colon).trim().toLowerCase()] = header.substr(colon + 1).trim()
result[header.substr(0, colon).trim().toLowerCase()] =
header.substr(colon + 1).trim()
}
return result
}, {})
Expand All @@ -73,13 +76,14 @@ if (credentials) {

nettime({
url: url,
credentials: credentials,
data: commander.data,
headers: headers,
httpVersion: commander['http1.0'] ? '1.0' : '1.1',
includeHeaders: commander.include,
method: commander.request || (commander.head ? 'HEAD'
: commander.data ? 'POST' : 'GET'),
headers: headers,
credentials: credentials,
outputFile: commander.output,
includeHeaders: commander.include,
rejectUnauthorized: !commander.insecure
})
.then(function (result) {
Expand Down
8 changes: 8 additions & 0 deletions lib/nettime.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ function nettime (options) {
})
.on('error', reject)

if (options.httpVersion === '1.0') {
const storeHeader = request._storeHeader
request._storeHeader = function (firstLine, headers) {
firstLine = firstLine.replace(/HTTP\/1.1\r\n$/, 'HTTP/1.0\r\n')
return storeHeader.call(request, firstLine, headers)
}
}

const inputData = options.data
if (inputData) {
request.write(inputData)
Expand Down
18 changes: 16 additions & 2 deletions tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ipAddress = '127.0.0.1'
const unsecurePort = 8899
const securePort = 9988
const servers = []
let lastHeaders, lastMethod, lastData
let lastHeaders, lastMethod, lastData, lastVersion

function createServer (protocol, port, options) {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -47,6 +47,7 @@ function serve (request, response) {

lastHeaders = request.headers
lastMethod = request.method
lastVersion = request.httpVersion
if (upload) {
lastData = ''
request.on('data', function (data) {
Expand Down Expand Up @@ -78,8 +79,9 @@ function makeRequest (protocol, host, port, path, options) {
const https = protocol === 'https'
const url = protocol + '://' + host + ':' + port + (path || '')
let credentials, headers, method, outputFile, returnResponse
let includeHeaders, data
let includeHeaders, data, httpVersion
if (options) {
httpVersion = options.httpVersion
if (options.username) {
credentials = options
} else if (options.method) {
Expand All @@ -101,6 +103,7 @@ function makeRequest (protocol, host, port, path, options) {
credentials: credentials,
data: data,
headers: headers,
httpVersion: httpVersion,
includeHeaders: includeHeaders,
method: method,
outputFile: outputFile,
Expand Down Expand Up @@ -355,6 +358,17 @@ test.test('test posting data', function (test) {
.then(test.end)
})

test.test('test HTTP 1.0', function (test) {
return makeRequest('http', ipAddress, unsecurePort, '/data', {
httpVersion: '1.0'
})
.then(result => {
test.equal(lastVersion, '1.0')
})
.catch(test.threw)
.then(test.end)
})

test.test('stop testing servers', function (test) {
stopServers()
test.end()
Expand Down

0 comments on commit 3cb303c

Please sign in to comment.