You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

84 lines
1.7 KiB

// Packages
import {parse} from 'url'
import http2 from 'spdy'
import fetch from 'node-fetch'
/**
* Returns a `fetch` version with a similar
* API to the browser's configured with a
* HTTP2 agent.
*
* It encodes `body` automatically as JSON.
*
* @param {String} host
* @return {Function} fetch
*/
export default class Agent {
constructor(url, {tls = true, debug} = {}) {
this._url = url
const parsed = parse(url)
this._host = parsed.hostname
this._port = parsed.port
this._protocol = parsed.protocol
this._debug = debug
if (tls) {
this._initAgent()
}
}
_initAgent() {
if (this._protocol !== 'https:') {
return
}
this._agent = http2.createAgent({
host: this._host,
port: this._port || 443
}).once('error', err => this._onError(err))
}
_onError(err) {
if (this._debug) {
console.log('> [debug] agent connection error', err.stack)
}
this._error = err
}
fetch(path, opts = {}) {
if (this._error) {
if (this._debug) {
console.log('> [debug] re-initializing agent after error')
}
this._error = null
this._initAgent()
}
const {body} = opts
if (this._agent) {
opts.agent = this._agent
}
if (body && typeof body === 'object' && typeof body.pipe !== 'function') {
opts.headers['Content-Type'] = 'application/json'
opts.body = JSON.stringify(body)
}
if (opts.body && typeof body.pipe !== 'function') {
opts.headers['Content-Length'] = Buffer.byteLength(opts.body)
}
return fetch(this._url + path, opts)
}
close() {
if (this._debug) {
console.log('> [debug] closing agent')
}
if (this._agent) {
this._agent.close()
}
}
}