WORK IN PROGRESS - API might change before first release
Thin wrapper around node's http/https client that provides promises based api.
- Queuing
- Streaming
- Automatic content decoding
- Custom CA and SSL/TLS validation
- Client side certificates
- Precise timing
- Bulk request
Installation:
npm install @connectedcars/httpclient
const { HttpClient } = require('@connectedcars/httpclient')
let httpClient = new HttpClient()
let response = await httpClient.get('http://localhost:3000/')
// {
// statusCode: 200,
// statusMessage: 'OK',
// data: Buffer([...])
// extras: [{...}] // http2 push responses
// }
Queuing is done on each endpoint(protocol, host and port combination, fx. https://localhost:3000/. Limits are applied globally and per endpoint.
let httpClient = new HttpClient({ maxTotalConcurrent: 4, maxConcurrent: 2, keepAlive: true })
let promises = []
for (let i = 0; i < 4; i++) {
promises.push(httpClient.get(`http://host1/ok`))
promises.push(httpClient.get(`http://host2/ok`))
promises.push(httpClient.post(`http://host2/ok`), null, 'Post data')
}
let results = await Promise.all(promises),
Download large file and pipe it to a write stream:
let stream = httpClient.getStream(`http://localhost/largefile`)
stream.pipe(fs.createWriteStream('/tmp/largefile'))
let response = await stream.response
Upload large file from read stream and save response body to file:
let response = httpClient.postStream(`http://localhost/echo`)
fs.createReadStream('/tmp/largefile').pipe(response)
response.pipe(fs.createWriteStream('/tmp/uploadresponsebody'))
let res = await response
let stream = httpClient.postStream(`http://localhost/echo`)
fs.createReadStream('/tmp/largefile').pipe(stream)
stream.pipe(fs.createWriteStream('/tmp/uploadresponsebody'))
let response = await stream.response
Upload large file from read stream and get body in response promise:
let stream = httpClient.postStream(`http://localhost/echo`, null, { writeStream: true })
fs.createReadStream('/tmp/largefile').pipe(stream)
let response = await stream.response
let data = response.data
Gzip and deflate are supported.
let response = await httpClient.get('http://localhost:3000/', {
"Accept-Encoding": 'gzip, deflate'
})
let data = response.data
Do bulk GET request and return in order of resolve:
let responses = httpClient.getBatch([
`http://localhost/delay/300`,
`http://localhost/delay/100`,
`http://localhost/delay/200`,
`http://localhost/delay/400`
])
for await (let response of responses) {
console.log(response.statusCode)
// Order would be 100, 200, 300, 400
}
Do bulk POST request and return in order of resolve:
let responses = httpClient.postBatch([
{ url: `http://localhost/echo`, headers: { 'Content-Type': 'application/json' }, data: '{ "payload": "1" }' },
{ url: `http://localhost/echo`, headers: { 'Content-Type': 'application/json' }, data: '{ "payload": "2" }' }
])
for await (let response of responses) {
console.log(response.statusCode)
}
Global http authentication handler:
let httpClient = new HttpClient( {
responseHandler: (res, nextReq, reqCount, options) => {
if(res.statusCode === 401 && reqCount < 2) {
nextReq.headers['Authorization'] = 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
return new Promise(resolve => setTimeout(resolve, 1000 * count)) // Delay next request
}
if(res.statusCode === 403) {
throw new Error("Failed")
}
return res
}
} )
let response = httpClient.get('http://localhost/test')
Local http authentication handler:
let response = httpClient.get('http://localhost/test', {
Authorization: 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
}, {
responseHandler: (res, nextReq, reqCount) => {
if(res.statusCode === 401 && reqCount < 2) {
nextReq.headers['Authorization'] = 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
return false
}
return res
}
})