WIP: initial prototype

- Renamed host configuration, now we use node(s)
- Updated Connection internals
- Added custom headers for Connection
This commit is contained in:
delvedor
2018-11-09 17:15:29 +01:00
parent 2d7dfdd7a0
commit 3dd4f01370
3 changed files with 56 additions and 69 deletions

View File

@ -19,8 +19,8 @@ const {
class Client extends EventEmitter {
constructor (opts = {}) {
super()
if (!opts.host) {
throw new ConfigurationError('Missing host option')
if (!opts.node && !opts.nodes) {
throw new ConfigurationError('Missing node(s) option')
}
if (opts.log === true) {
@ -70,7 +70,7 @@ class Client extends EventEmitter {
})
// Add the connections before initialize the Transport
this[kConnectionPool].addConnection(options.host)
this[kConnectionPool].addConnection(options.node || options.nodes)
this[kTransport] = new options.Transport({
emit: this.emit.bind(this),
@ -110,5 +110,5 @@ module.exports = {
Transport,
ConnectionPool,
Serializer,
symbols
...symbols
}

View File

@ -9,11 +9,10 @@ const { TimeoutError } = require('./errors')
class Connection {
constructor (opts = {}) {
assert(opts.host, 'Missing host data')
this.host = urlToOptions(opts.host)
this.ssl = opts.host.ssl || opts.ssl || null
this.id = opts.id || opts.host.href
this.url = opts.url
this.ssl = opts.ssl || null
this.id = opts.id || opts.url.href
this.headers = opts.headers || null
this.deadCount = 0
this.resurrectTimeout = 0
@ -26,12 +25,12 @@ class Connection {
keepAliveMsecs: 1000,
maxSockets: Infinity,
maxFreeSockets: 256
}, opts.host.agent || opts.agent)
this._agent = this.host.protocol === 'http:'
}, opts.agent || opts.agent)
this._agent = this.url.protocol === 'http:'
? new http.Agent(agentOptions)
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
this.makeRequest = this.host.protocol === 'http:'
this.makeRequest = this.url.protocol === 'http:'
? http.request
: https.request
}
@ -42,7 +41,7 @@ class Connection {
params.agent = this._agent
debug('Starting a new request', params)
const request = this.makeRequest(buildRequestObject(this.host, params))
const request = this.makeRequest(this.buildRequestObject(params))
// listen for the response event
// TODO: handle redirects?
@ -115,6 +114,48 @@ class Connection {
)
this._status = status
}
buildRequestObject (params) {
const url = this.url
const request = {
protocol: url.protocol,
hostname: url.hostname[0] === '['
? url.hostname.slice(1, -1)
: url.hostname,
hash: url.hash,
search: url.search,
pathname: url.pathname,
path: '',
href: url.href,
port: url.port,
headers: this.headers,
auth: !!url.username === true || !!url.password === true
? `${url.username}:${url.password}`
: undefined
}
const paramsKeys = Object.keys(params)
for (var i = 0, len = paramsKeys.length; i < len; i++) {
var key = paramsKeys[i]
if (key === 'path') {
request.pathname = resolve(request.pathname, params[key])
} else if (key === 'querystring' && !!params[key] === true) {
if (request.search === '') {
request.search = '?' + params[key]
} else {
request.search += '&' + params[key]
}
} else if (key === 'headers') {
request.headers = Object.assign({}, request.headers, params.headers)
} else {
request[key] = params[key]
}
}
request.path = request.pathname + request.search
return request
}
}
Connection.statuses = {
@ -156,58 +197,4 @@ function resolve (host, path) {
}
}
function buildRequestObject (host, request) {
var merged = {}
var hostKeys = Object.keys(host)
var requestKeys = Object.keys(request)
for (var i = 0, len = hostKeys.length; i < len; i++) {
var key = hostKeys[i]
merged[key] = host[key]
}
for (i = 0, len = requestKeys.length; i < len; i++) {
key = requestKeys[i]
if (key === 'path') {
merged.pathname = resolve(merged.pathname, request[key])
} else if (key === 'querystring' && !!request[key] === true) {
if (merged.search === '') {
merged.search = '?' + request[key]
} else {
merged.search += '&' + request[key]
}
} else {
merged[key] = request[key]
}
}
merged.path = merged.pathname + merged.search
return merged
}
// Utility function that converts a URL object into an ordinary
// options object as expected by the http.request and https.request APIs.
// https://github.com/nodejs/node/blob/v11.0.0/lib/internal/url.js#L1324
function urlToOptions (url) {
var options = {
protocol: url.protocol,
hostname: url.hostname.startsWith('[')
? url.hostname.slice(1, -1)
: url.hostname,
hash: url.hash,
search: url.search,
pathname: url.pathname,
path: `${url.pathname}${url.search}`,
href: url.href
}
if (url.port !== '') {
options.port = Number(url.port)
}
if (url.username || url.password) {
options.auth = `${url.username}:${url.password}`
}
return options
}
module.exports = Connection

View File

@ -290,7 +290,7 @@ class ConnectionPool {
? address
: 'http://' + address
hosts.push({
host: new URL(address),
url: new URL(address),
id: ids[i],
roles: node.roles.reduce((acc, role) => {
acc[role] = true
@ -310,7 +310,7 @@ class ConnectionPool {
*/
urlToHost (url) {
return {
host: new URL(url)
url: new URL(url)
}
}
}