Comparing version 8.1.2 to 8.2.0
@@ -20,2 +20,6 @@ 'use strict'; | ||
internals.defaults = { | ||
httpClient: { | ||
request: Wreck.request.bind(Wreck), | ||
parseCacheControl: Wreck.parseCacheControl.bind(Wreck) | ||
}, | ||
xforward: false, | ||
@@ -32,2 +36,6 @@ passThrough: false, | ||
internals.schema = Joi.object({ | ||
httpClient: Joi.object({ | ||
request: Joi.func(), | ||
parseCacheControl: Joi.func() | ||
}), | ||
host: Joi.string(), | ||
@@ -159,4 +167,5 @@ port: Joi.number().integer(), | ||
} | ||
const promise = Wreck.request(request.method, uri, options); | ||
const promise = settings.httpClient.request(request.method, uri, options); | ||
if (settings.onRequest) { | ||
@@ -189,3 +198,3 @@ settings.onRequest(promise.req); | ||
if (cacheControlHeader) { | ||
const cacheControl = Wreck.parseCacheControl(cacheControlHeader); | ||
const cacheControl = settings.httpClient.parseCacheControl(cacheControlHeader); | ||
if (cacheControl) { | ||
@@ -234,3 +243,3 @@ ttl = cacheControl['max-age'] * 1000; | ||
.replace(/{port}/g, request.server.info.port) | ||
.replace(/{path}/g, request.url.path); | ||
.replace(/{path}/g, request.path); | ||
@@ -237,0 +246,0 @@ Object.keys(request.params).forEach((key) => { |
{ | ||
"name": "h2o2", | ||
"description": "Proxy handler plugin for hapi.js", | ||
"version": "8.1.2", | ||
"version": "8.2.0", | ||
"repository": "git://github.com/hapijs/h2o2", | ||
@@ -6,0 +6,0 @@ "main": "lib/index.js", |
@@ -43,3 +43,3 @@ # h2o2 | ||
The plugin can be registered with an optional object specifying defaults to be applied to the proxy handler object. | ||
The plugin can be registered with an optional object specifying defaults to be applied to the proxy handler object. | ||
@@ -54,4 +54,5 @@ The proxy handler object has the following properties: | ||
* `uri` - absolute URI used instead of host, port, protocol, path, and query. Cannot be used with `host`, `port`, `protocol`, or `mapUri`. | ||
* `httpClient` - an http client that abides by the Wreck interface. Defaults to [`wreck`](https://github.com/hapijs/wreck). | ||
* `passThrough` - if set to `true`, it forwards the headers from the client to the upstream service, headers sent from the upstream service will also be forwarded to the client. Defaults to `false`. | ||
* `localStatePassThrough` - if set to`false`, any locally defined state is removed from incoming requests before being sent to the upstream service. This value can be overridden on a per state basis via the `server.state()``passThrough` option. Defaults to `false` | ||
* `localStatePassThrough` - if set to`false`, any locally defined state is removed from incoming requests before being sent to the upstream service. This value can be overridden on a per state basis via the `server.state()` `passThrough` option. Defaults to `false` | ||
* `acceptEncoding` - if set to `false`, does not pass-through the 'Accept-Encoding' HTTP header which is useful for the `onResponse` post-processing to avoid receiving an encoded response. Can only be used together with `passThrough`. Defaults to `true` (passing header). | ||
@@ -68,7 +69,7 @@ * `rejectUnauthorized` - sets the `rejectUnauthorized` property on the https [agent](http://nodejs.org/api/https.html#https_https_request_options_callback) making the request. This value is only used when the proxied server uses TLS/SSL. If set it will override the node.js `rejectUnauthorized` property. If `false` then ssl errors will be ignored. When `true` the server certificate is verified and an 500 response will be sent when verification fails. This shouldn't be used alongside the `agent` setting as the `agent` will be used instead. Defaults to the https agent default value of `true`. | ||
* `req` - the [wreck] (https://github.com/hapijs/wreck) request to the upstream server. | ||
* `onResponse` - a custom function for processing the response from the upstream service before sending to the client. Useful for custom error handling of responses from the proxied endpoint or other payload manipulation. Function signature is `function (err, res, request, reply, settings, ttl)` where: | ||
* `onResponse` - a custom function for processing the response from the upstream service before sending to the client. Useful for custom error handling of responses from the proxied endpoint or other payload manipulation. Function signature is `function (err, res, request, h, settings, ttl)` where: | ||
* `err` - internal or upstream error returned from attempting to contact the upstream proxy. | ||
* `res` - the node response object received from the upstream service. `res` is a readable stream (use the [wreck](https://github.com/hapijs/wreck) module `read` method to easily convert it to a Buffer or string). | ||
* `request` - is the incoming [request object](http://hapijs.com/api#request-object). | ||
* `reply` - the [reply interface](http://hapijs.com/api#reply-interface) function. | ||
* `h` - the [response toolkit](https://hapijs.com/api#response-toolkit). | ||
* `settings` - the proxy handler configuration. | ||
@@ -80,4 +81,4 @@ * `ttl` - the upstream TTL in milliseconds if `proxy.ttl` it set to `'upstream'` and the upstream response included a valid 'Cache-Control' header with 'max-age'. | ||
* `secureProtocol` - [TLS](http://nodejs.org/api/tls.html) flag indicating the SSL method to use, e.g. `SSLv3_method` | ||
to force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible [SSL_METHODS](http://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_PROTOCOL_METHODS). | ||
* `ciphers` - [TLS](https://nodejs.org/api/tls.html#tls_modifying_the_default_tls_cipher_suite) list of TLS ciphers to override node's default. | ||
to force SSL version 3. The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible [SSL_METHODS](https://www.openssl.org/docs/man1.0.2/ssl/ssl.html). | ||
* `ciphers` - [TLS](https://nodejs.org/api/tls.html#tls_modifying_the_default_tls_cipher_suite) list of TLS ciphers to override node's default. | ||
The possible values depend on your installation of OpenSSL. Read the official OpenSSL docs for possible [TLS_CIPHERS](https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT). | ||
@@ -195,3 +196,3 @@ * `downstreamResponseTime` - logs the time spent processing the downstream request using [process.hrtime](https://nodejs.org/api/process.html#process_process_hrtime_time). Defaults to `false`. | ||
}, | ||
onResponse: function (err, res, request, reply, settings, ttl) { | ||
onResponse: function (err, res, request, h, settings, ttl) { | ||
@@ -202,3 +203,5 @@ console.log('receiving the response from the upstream.'); | ||
console.log('some payload manipulation if you want to.') | ||
reply(payload).headers = res.headers; | ||
const response = h.response(payload); | ||
response.headers = res.headers; | ||
return response; | ||
}); | ||
@@ -211,1 +214,25 @@ } | ||
``` | ||
### Using a custom http client | ||
By default, `h2o2` uses Wreck to perform requests. A custom http client can be provided by passing a client to `httpClient`, as long as it abides by the [`wreck`](https://github.com/hapijs/wreck) interface. The two functions that `h2o2` utilizes are `request()` and `parseCacheControl()`. | ||
```javascript | ||
server.route({ | ||
method: 'GET', | ||
path: '/', | ||
handler: { | ||
proxy: { | ||
httpClient: { | ||
request(method, uri, options) { | ||
return axios({ | ||
method, | ||
url: 'https://some.upstream.service.com/' | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
``` |
@@ -53,13 +53,13 @@ 'use strict'; | ||
let maxSockets; | ||
const orig = Wreck.request; | ||
Wreck.request = function (method, uri, options, callback) { | ||
const httpClient = { | ||
request(method, uri, options, callback) { | ||
Wreck.request = orig; | ||
maxSockets = options.agent.maxSockets; | ||
maxSockets = options.agent.maxSockets; | ||
return { statusCode: 200 }; | ||
return { statusCode: 200 }; | ||
} | ||
}; | ||
const server = await provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { proxy: { host: 'localhost', maxSockets: 213 } } }); | ||
server.route({ method: 'GET', path: '/', handler: { proxy: { host: 'localhost', httpClient, maxSockets: 213 } } }); | ||
await server.inject('/'); | ||
@@ -72,13 +72,13 @@ expect(maxSockets).to.equal(213); | ||
let agent; | ||
const orig = Wreck.request; | ||
Wreck.request = function (method, uri, options) { | ||
const httpClient = { | ||
request(method, uri, options) { | ||
Wreck.request = orig; | ||
agent = options.agent; | ||
agent = options.agent; | ||
return { statusCode: 200 }; | ||
return { statusCode: 200 }; | ||
} | ||
}; | ||
const server = await provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { proxy: { host: 'localhost', maxSockets: false } } }); | ||
server.route({ method: 'GET', path: '/', handler: { proxy: { host: 'localhost', httpClient, maxSockets: false } } }); | ||
await server.inject('/'); | ||
@@ -1475,11 +1475,11 @@ expect(agent).to.equal(undefined); | ||
const requestFn = Wreck.request; | ||
Wreck.request = function (method, url, options) { | ||
const httpClient = { | ||
request(method, uri, options, callback) { | ||
Wreck.request = requestFn; | ||
expect(options.headers['content-type']).to.equal('application/json'); | ||
expect(options.headers['Content-Type']).to.not.exist(); | ||
throw new Error('placeholder'); | ||
expect(options.headers['content-type']).to.equal('application/json'); | ||
expect(options.headers['Content-Type']).to.not.exist(); | ||
throw new Error('placeholder'); | ||
} | ||
}; | ||
server.route({ method: 'GET', path: '/test', handler: { proxy: { uri: 'http://localhost', passThrough: true } } }); | ||
server.route({ method: 'GET', path: '/test', handler: { proxy: { uri: 'http://localhost', httpClient, passThrough: true } } }); | ||
await server.inject({ method: 'GET', url: '/test', headers: { 'Content-Type': 'application/json' } }); | ||
@@ -1493,10 +1493,10 @@ }); | ||
const requestFn = Wreck.request; | ||
Wreck.request = function (method, url, options) { | ||
const httpClient = { | ||
request(method, uri, options, callback) { | ||
Wreck.request = requestFn; | ||
expect(options.agent).to.equal(agent); | ||
return { statusCode: 200 }; | ||
expect(options.agent).to.equal(agent); | ||
return { statusCode: 200 }; | ||
} | ||
}; | ||
server.route({ method: 'GET', path: '/agenttest', handler: { proxy: { uri: 'http://localhost', agent } } }); | ||
server.route({ method: 'GET', path: '/agenttest', handler: { proxy: { uri: 'http://localhost', httpClient, agent } } }); | ||
await server.inject({ method: 'GET', url: '/agenttest', headers: {} }, (res) => { }); | ||
@@ -1851,2 +1851,21 @@ }); | ||
}); | ||
it('uses a custom http-client', async () => { | ||
const upstream = Hapi.server(); | ||
upstream.route({ method: 'GET', path: '/', handler: () => 'ok' }); | ||
await upstream.start(); | ||
const httpClient = { | ||
request: Wreck.request.bind(Wreck), | ||
parseCacheControl: Wreck.parseCacheControl.bind(Wreck) | ||
}; | ||
const server = await provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { proxy: { host: 'localhost', port: upstream.info.port, httpClient } } }); | ||
const res = await server.inject('/'); | ||
expect(res.payload).to.equal('ok'); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
88100
9
1608
231