Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
5
node_modules/express-http-proxy/.eslintignore
generated
vendored
Normal file
5
node_modules/express-http-proxy/.eslintignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/coverage
|
||||
/scripts
|
||||
/node_modules
|
||||
/jsdoc
|
||||
/locales
|
||||
168
node_modules/express-http-proxy/.eslintrc
generated
vendored
Normal file
168
node_modules/express-http-proxy/.eslintrc
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jquery": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
},
|
||||
"globals": {},
|
||||
"parserOptions": { "ecmaVersion": 8 },
|
||||
"rules": {
|
||||
"camelcase": [
|
||||
2,
|
||||
{
|
||||
"properties": "always"
|
||||
}
|
||||
],
|
||||
"eqeqeq": 2,
|
||||
"indent": [
|
||||
"error",
|
||||
2,
|
||||
{
|
||||
"ArrayExpression": 1,
|
||||
"CallExpression": {"arguments": 1},
|
||||
"FunctionDeclaration": {"body": 1, "parameters": 2},
|
||||
"MemberExpression": 1,
|
||||
"ObjectExpression": 1,
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"no-use-before-define": [
|
||||
2,
|
||||
{
|
||||
"functions": false
|
||||
}
|
||||
],
|
||||
"max-len": [
|
||||
2,
|
||||
120
|
||||
],
|
||||
"max-depth": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"complexity": [
|
||||
2,
|
||||
15
|
||||
],
|
||||
"new-cap": 2,
|
||||
"quotes": [
|
||||
2,
|
||||
"single",
|
||||
{
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
],
|
||||
"strict": [
|
||||
2,
|
||||
"global"
|
||||
],
|
||||
"no-undef": 2,
|
||||
"no-unused-vars": 2,
|
||||
"no-eq-null": 2,
|
||||
"space-before-function-paren": ["error", {
|
||||
"anonymous": "always",
|
||||
"named": "never"
|
||||
}],
|
||||
"no-empty": [
|
||||
2,
|
||||
{
|
||||
"allowEmptyCatch": true
|
||||
}
|
||||
],
|
||||
"object-curly-spacing": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"space-in-parens": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"quote-props": [
|
||||
2,
|
||||
"as-needed"
|
||||
],
|
||||
"key-spacing": [
|
||||
2,
|
||||
{
|
||||
"beforeColon": false,
|
||||
"afterColon": true
|
||||
}
|
||||
],
|
||||
"space-unary-ops": [
|
||||
2,
|
||||
{
|
||||
"words": false,
|
||||
"nonwords": false
|
||||
}
|
||||
],
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"comma-dangle": 0,
|
||||
"comma-spacing": [
|
||||
2,
|
||||
{
|
||||
"after": true,
|
||||
"before": false
|
||||
}
|
||||
],
|
||||
"no-with": 2,
|
||||
"brace-style": [
|
||||
2,
|
||||
"1tbs",
|
||||
{
|
||||
"allowSingleLine": true
|
||||
}
|
||||
],
|
||||
"no-multiple-empty-lines": 2,
|
||||
"no-multi-str": 2,
|
||||
"one-var": [
|
||||
2,
|
||||
"never"
|
||||
],
|
||||
"semi-spacing": [
|
||||
2,
|
||||
{
|
||||
"before": false,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"space-before-blocks": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"wrap-iife": 2,
|
||||
"comma-style": [
|
||||
2,
|
||||
"last"
|
||||
],
|
||||
"space-infix-ops": 2,
|
||||
"eol-last": 2,
|
||||
"dot-notation": 2,
|
||||
"curly": [
|
||||
2,
|
||||
"all"
|
||||
],
|
||||
"keyword-spacing": [
|
||||
2,
|
||||
{}
|
||||
],
|
||||
"lines-around-comment": [
|
||||
2,
|
||||
{ "afterLineComment": true, "allowBlockEnd": true }
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"consistent-this": [
|
||||
2,
|
||||
"self"
|
||||
],
|
||||
"linebreak-style": [
|
||||
2,
|
||||
"unix"
|
||||
]
|
||||
}
|
||||
}
|
||||
4
node_modules/express-http-proxy/.travis.yml
generated
vendored
Normal file
4
node_modules/express-http-proxy/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "6"
|
||||
- "8"
|
||||
21
node_modules/express-http-proxy/LICENSE-MIT
generated
vendored
Normal file
21
node_modules/express-http-proxy/LICENSE-MIT
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
Copyright (c) 2013 villadora <jky239@gmail.com>, contributors
|
||||
http://kael.me/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
591
node_modules/express-http-proxy/README.md
generated
vendored
Normal file
591
node_modules/express-http-proxy/README.md
generated
vendored
Normal file
@@ -0,0 +1,591 @@
|
||||
# express-http-proxy [](http://badge.fury.io/js/express-http-proxy) [](https://travis-ci.org/villadora/express-http-proxy) [](https://gemnasium.com/villadora/express-http-proxy)
|
||||
|
||||
Express middleware to proxy request to another host and pass response back to original caller.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
$ npm install express-http-proxy --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
```js
|
||||
proxy(host, options);
|
||||
```
|
||||
|
||||
### Example:
|
||||
To proxy URLS starting with '/proxy' to the host 'www.google.com':
|
||||
|
||||
```js
|
||||
var proxy = require('express-http-proxy');
|
||||
var app = require('express')();
|
||||
|
||||
app.use('/proxy', proxy('www.google.com'));
|
||||
```
|
||||
|
||||
### Streaming
|
||||
|
||||
Proxy requests and user responses are piped/streamed/chunked by default.
|
||||
|
||||
If you define a response modifier (userResDecorator, userResHeaderDecorator),
|
||||
or need to inspect the response before continuing (maybeSkipToNext), streaming
|
||||
is disabled, and the request and response are buffered.
|
||||
This can cause performance issues with large payloads.
|
||||
|
||||
### Promises
|
||||
|
||||
Many function hooks support Promises.
|
||||
If any Promise is rejected, ```next(x)``` is called in the hosting application, where ```x``` is whatever you pass to ```Promise.reject```;
|
||||
|
||||
|
||||
e.g.
|
||||
```js
|
||||
app.use(proxy('/reject-promise', {
|
||||
proxyReqOptDecorator: function() {
|
||||
return Promise.reject('An arbitrary rejection message.');
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
eventually calls
|
||||
|
||||
```js
|
||||
next('An arbitrary rejection messasage');
|
||||
```
|
||||
|
||||
### Host
|
||||
|
||||
The first positional argument is for the proxy host; in many cases you will use a static string here, eg.
|
||||
|
||||
```js
|
||||
app.use('/', proxy('http://google.com'))
|
||||
```
|
||||
|
||||
However, this argument can also be a function, and that function can be
|
||||
memoized or computed on each request, based on the setting of
|
||||
```memoizeHost```.
|
||||
|
||||
```js
|
||||
function selectProxyHost() {
|
||||
return (new Date() % 2) ? 'http://google.com' : 'http://altavista.com';
|
||||
}
|
||||
|
||||
app.use('/', proxy(selectProxyHost));
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
#### proxyReqPathResolver (supports Promises)
|
||||
|
||||
Note: In ```express-http-proxy```, the ```path``` is considered the portion of
|
||||
the url after the host, and including all query params. E.g. for the URL
|
||||
```http://smoogle.com/search/path?q=123```; the path is
|
||||
```/search/path?q=123```. Authors using this resolver must also handle the query parameter portion of the path.
|
||||
|
||||
Provide a proxyReqPathResolver function if you'd like to
|
||||
operate on the path before issuing the proxy request. Use a Promise for async
|
||||
operations.
|
||||
|
||||
```js
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqPathResolver: function (req) {
|
||||
var parts = req.url.split('?');
|
||||
var queryString = parts[1];
|
||||
var updatedPath = parts[0].replace(/test/, 'tent');
|
||||
return updatedPath + (queryString ? '?' + queryString : '');
|
||||
}
|
||||
}));
|
||||
```
|
||||
Promise form
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('localhost:12345', {
|
||||
proxyReqPathResolver: function(req) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(function () { // simulate async
|
||||
var parts = req.url.split('?');
|
||||
var queryString = parts[1];
|
||||
var updatedPath = parts[0].replace(/test/, 'tent');
|
||||
var resolvedPathValue = updatedPath + (queryString ? '?' + queryString : '');
|
||||
resolve(resolvedPathValue);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
#### forwardPath
|
||||
|
||||
DEPRECATED. See proxyReqPathResolver
|
||||
|
||||
#### forwardPathAsync
|
||||
|
||||
DEPRECATED. See proxyReqPathResolver
|
||||
|
||||
#### filter (supports Promises)
|
||||
|
||||
The ```filter``` option can be used to limit what requests are proxied. Return
|
||||
```true``` to continue to execute proxy; return false-y to skip proxy for this
|
||||
request.
|
||||
|
||||
For example, if you only want to proxy get request:
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
filter: function(req, res) {
|
||||
return req.method == 'GET';
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
Promise form:
|
||||
|
||||
```js
|
||||
app.use(proxy('localhost:12346', {
|
||||
filter: function (req, res) {
|
||||
return new Promise(function (resolve) {
|
||||
resolve(req.method === 'GET');
|
||||
});
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
Note that in the previous example, `resolve(false)` will execute the happy path
|
||||
for filter here (skipping the rest of the proxy, and calling `next()`).
|
||||
`reject()` will also skip the rest of proxy and call `next()`.
|
||||
|
||||
#### userResDecorator (was: intercept) (supports Promise)
|
||||
|
||||
You can modify the proxy's response before sending it to the client.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
userResDecorator: function(proxyRes, proxyResData, userReq, userRes) {
|
||||
data = JSON.parse(proxyResData.toString('utf8'));
|
||||
data.newProperty = 'exciting data';
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
```js
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function(proxyRes, proxyResData) {
|
||||
return new Promise(function(resolve) {
|
||||
proxyResData.funkyMessage = 'oi io oo ii';
|
||||
setTimeout(function() {
|
||||
resolve(proxyResData);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
##### 304 - Not Modified
|
||||
|
||||
When your proxied service returns 304, not modified, this step will be skipped, since there is no body to decorate.
|
||||
|
||||
##### exploiting references
|
||||
The intent is that this be used to modify the proxy response data only.
|
||||
|
||||
Note:
|
||||
The other arguments (proxyRes, userReq, userRes) are passed by reference, so
|
||||
you *can* currently exploit this to modify either response's headers, for
|
||||
instance, but this is not a reliable interface. I expect to close this
|
||||
exploit in a future release, while providing an additional hook for mutating
|
||||
the userRes before sending.
|
||||
|
||||
##### gzip responses
|
||||
|
||||
If your proxy response is gzipped, this program will automatically unzip
|
||||
it before passing to your function, then zip it back up before piping it to the
|
||||
user response. There is currently no way to short-circuit this behavior.
|
||||
|
||||
#### limit
|
||||
|
||||
This sets the body size limit (default: `1mb`). If the body size is larger than the specified (or default) limit,
|
||||
a `413 Request Entity Too Large` error will be returned. See [bytes.js](https://www.npmjs.com/package/bytes) for
|
||||
a list of supported formats.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
limit: '5mb'
|
||||
}));
|
||||
```
|
||||
|
||||
#### memoizeHost
|
||||
|
||||
Defaults to ```true```.
|
||||
|
||||
When true, the ```host``` argument will be parsed on first request, and
|
||||
memoized for subsequent requests.
|
||||
|
||||
When ```false```, ```host``` argument will be parsed on each request.
|
||||
|
||||
E.g.,
|
||||
|
||||
```js
|
||||
|
||||
function coinToss() { return Math.random() > .5 }
|
||||
function getHost() { return coinToss() ? 'http://yahoo.com' : 'http://google.com' }
|
||||
|
||||
app.use(proxy(getHost, {
|
||||
memoizeHost: false
|
||||
}))
|
||||
```
|
||||
|
||||
In this example, when ```memoizeHost:false```, the coinToss occurs on each
|
||||
request, and each request could get either value.
|
||||
|
||||
Conversely, When ```memoizeHost:true```, the coinToss would occur on the first
|
||||
request, and all additional requests would return the value resolved on the
|
||||
first request.
|
||||
|
||||
|
||||
### userResHeaderDecorator
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
userResHeaderDecorator(headers, userReq, userRes, proxyReq, proxyRes) {
|
||||
// recieves an Object of headers, returns an Object of headers.
|
||||
return headers;
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
|
||||
#### decorateRequest
|
||||
|
||||
REMOVED: See ```proxyReqOptDecorator``` and ```proxyReqBodyDecorator```.
|
||||
|
||||
|
||||
#### skipToNextHandlerFilter(supports Promise form)
|
||||
(experimental: this interface may change in upcoming versions)
|
||||
|
||||
Allows you to inspect the proxy response, and decide if you want to continue processing (via express-http-proxy) or call ```next()``` to return control to express.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
skipToNextHandlerFilter: function(proxyRes) {
|
||||
return proxyRes.statusCode === 404;
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
### proxyErrorHandler
|
||||
|
||||
By default, ```express-http-proxy``` will pass any errors except ECONNRESET to
|
||||
next, so that your application can handle or react to them, or just drop
|
||||
through to your default error handling. ECONNRESET errors are immediately
|
||||
returned to the user for historical reasons.
|
||||
|
||||
If you would like to modify this behavior, you can provide your own ```proxyErrorHandler```.
|
||||
|
||||
|
||||
```js
|
||||
// Example of skipping all error handling.
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
proxyErrorHandler: function(err, res, next) {
|
||||
next(err);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
// Example of rolling your own
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
proxyErrorHandler: function(err, res, next) {
|
||||
switch (err && err.code) {
|
||||
case 'ECONNRESET': { return res.status(405).send('504 became 405'); }
|
||||
case 'ECONNREFUSED': { return res.status(200).send('gotcher back'); }
|
||||
default: { next(err); }
|
||||
}
|
||||
}}));
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### proxyReqOptDecorator (supports Promise form)
|
||||
|
||||
You can override most request options before issuing the proxyRequest.
|
||||
proxyReqOpt represents the options argument passed to the (http|https).request
|
||||
module.
|
||||
|
||||
NOTE: req.path cannot be changed via this method; use ```proxyReqPathResolver``` instead. (see https://github.com/villadora/express-http-proxy/issues/243)
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
|
||||
// you can update headers
|
||||
proxyReqOpts.headers['Content-Type'] = 'text/html';
|
||||
// you can change the method
|
||||
proxyReqOpts.method = 'GET';
|
||||
return proxyReqOpts;
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
You can use a Promise for async style.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
proxyReqOpts.headers['Content-Type'] = 'text/html';
|
||||
resolve(proxyReqOpts);
|
||||
})
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
#### proxyReqBodyDecorator (supports Promise form)
|
||||
|
||||
You can mutate the body content before sending the proxyRequest.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
proxyReqBodyDecorator: function(bodyContent, srcReq) {
|
||||
return bodyContent.split('').reverse().join('');
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
You can use a Promise for async style.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
proxyReqBodyDecorator: function(proxyReq, srcReq) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
http.get('http://dev/null', function (err, res) {
|
||||
if (err) { reject(err); }
|
||||
resolve(res);
|
||||
});
|
||||
})
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
#### https
|
||||
|
||||
Normally, your proxy request will be made on the same protocol as the `host`
|
||||
parameter. If you'd like to force the proxy request to be https, use this
|
||||
option.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
https: true
|
||||
}));
|
||||
```
|
||||
|
||||
#### preserveHostHdr
|
||||
|
||||
You can copy the host HTTP header to the proxied express server using the `preserveHostHdr` option.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
preserveHostHdr: true
|
||||
}));
|
||||
```
|
||||
|
||||
#### parseReqBody
|
||||
|
||||
The ```parseReqBody``` option allows you to control parsing the request body.
|
||||
For example, disabling body parsing is useful for large uploads where it would be inefficient
|
||||
to hold the data in memory.
|
||||
|
||||
##### Note: this setting is required for binary uploads. A future version of this library may handle this for you.
|
||||
|
||||
This defaults to true in order to preserve legacy behavior.
|
||||
|
||||
When false, no action will be taken on the body and accordingly ```req.body``` will no longer be set.
|
||||
|
||||
Note that setting this to false overrides ```reqAsBuffer``` and ```reqBodyEncoding``` below.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
parseReqBody: false
|
||||
}));
|
||||
```
|
||||
|
||||
#### reqAsBuffer
|
||||
|
||||
Note: this is an experimental feature. ymmv
|
||||
|
||||
The ```reqAsBuffer``` option allows you to ensure the req body is encoded as a Node
|
||||
```Buffer``` when sending a proxied request. Any value for this is truthy.
|
||||
|
||||
This defaults to to false in order to preserve legacy behavior. Note that
|
||||
the value of ```reqBodyEnconding``` is used as the encoding when coercing strings
|
||||
(and stringified JSON) to Buffer.
|
||||
|
||||
Ignored if ```parseReqBody``` is set to false.
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
reqAsBuffer: true
|
||||
}));
|
||||
```
|
||||
|
||||
#### reqBodyEncoding
|
||||
|
||||
Encoding used to decode request body. Defaults to ```utf-8```.
|
||||
|
||||
Use ```null``` to preserve as Buffer when proxied request body is a Buffer. (e.g image upload)
|
||||
Accept any values supported by [raw-body](https://www.npmjs.com/package/raw-body#readme).
|
||||
|
||||
The same encoding is used in the intercept method.
|
||||
|
||||
Ignored if ```parseReqBody``` is set to false.
|
||||
|
||||
```js
|
||||
app.use('/post', proxy('httpbin.org', {
|
||||
reqBodyEncoding: null
|
||||
}));
|
||||
```
|
||||
|
||||
#### timeout
|
||||
|
||||
By default, node does not express a timeout on connections.
|
||||
Use timeout option to impose a specific timeout.
|
||||
Timed-out requests will respond with 504 status code and a X-Timeout-Reason header.
|
||||
|
||||
```js
|
||||
app.use('/', proxy('httpbin.org', {
|
||||
timeout: 2000 // in milliseconds, two seconds
|
||||
}));
|
||||
```
|
||||
|
||||
## Trace debugging
|
||||
|
||||
The node-debug module is used to provide a trace debugging capability.
|
||||
|
||||
```
|
||||
DEBUG=express-http-proxy npm run YOUR_PROGRAM
|
||||
DEBUG=express-http-proxy npm run YOUR_PROGRAM | grep 'express-http-proxy' # to filter down to just these messages
|
||||
```
|
||||
|
||||
Will trace the execution of the express-http-proxy module in order to aide debugging.
|
||||
|
||||
|
||||
|
||||
|
||||
## Upgrade to 1.0, transition guide and breaking changes
|
||||
|
||||
1.
|
||||
```decorateRequest``` has been REMOVED, and will generate an error when called. See ```proxyReqOptDecorator``` and ```proxyReqBodyDecorator```.
|
||||
|
||||
Resolution: Most authors will simply need to change the method name for their
|
||||
decorateRequest method; if author was decorating reqOpts and reqBody in the
|
||||
same method, this will need to be split up.
|
||||
|
||||
|
||||
2.
|
||||
```intercept``` has been REMOVED, and will generate an error when called. See ```userResDecorator```.
|
||||
|
||||
Resolution: Most authors will simply need to change the method name from ```intercept``` to ```userResDecorator```, and exit the method by returning the value, rather than passing it to a callback. E.g.:
|
||||
|
||||
Before:
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
intercept: function(proxyRes, proxyResData, userReq, userRes, cb) {
|
||||
data = JSON.parse(proxyResData.toString('utf8'));
|
||||
data.newProperty = 'exciting data';
|
||||
cb(null, JSON.stringify(data));
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
Now:
|
||||
|
||||
```js
|
||||
app.use('/proxy', proxy('www.google.com', {
|
||||
userResDecorator: function(proxyRes, proxyResData, userReq, userRes) {
|
||||
data = JSON.parse(proxyResData.toString('utf8'));
|
||||
data.newProperty = 'exciting data';
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
}));
|
||||
```
|
||||
|
||||
3.
|
||||
```forwardPath``` and ```forwardPathAsync``` have been DEPRECATED and will generate a warning when called. See ```proxyReqPathResolver```.
|
||||
|
||||
Resolution: Simple update the name of either ```forwardPath``` or ```forwardPathAsync``` to ```proxyReqPathResolver```.
|
||||
|
||||
## When errors occur on your proxy server
|
||||
|
||||
When your proxy server responds with an error, express-http-proxy returns a response with the same status code. See ```test/catchingErrors``` for syntax details.
|
||||
|
||||
When your proxy server times out, express-http-proxy will continue to wait indefinitely for a response, unless you define a ```timeout``` as described above.
|
||||
|
||||
|
||||
## Questions
|
||||
|
||||
### Q: Does it support https proxy?
|
||||
|
||||
The library will automatically use https if the provided path has 'https://' or ':443'. You may also set option ```https``` to true to always use https.
|
||||
|
||||
You can use ```proxyReqOptDecorator``` to ammend any auth or challenge headers required to succeed https.
|
||||
|
||||
### Q: How can I support non-standard certificate chains?
|
||||
|
||||
You can use the ability to decorate the proxy request prior to sending. See ```proxyReqOptDecorator``` for more details.
|
||||
|
||||
```js
|
||||
app.use('/', proxy('internalhost.example.com', {
|
||||
proxyReqOptDecorator: function(proxyReqOpts, originalReq) {
|
||||
proxyReqOpts.ca = [caCert, intermediaryCert]
|
||||
return proxyReqOpts;
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Q: How to ignore self-signed certificates ?
|
||||
|
||||
You can set the `rejectUnauthorized` value in proxy request options prior to sending. See ```proxyReqOptDecorator``` for more details.
|
||||
|
||||
```js
|
||||
app.use('/', proxy('internalhost.example.com', {
|
||||
proxyReqOptDecorator: function(proxyReqOpts, originalReq) {
|
||||
proxyReqOpts.rejectUnauthorized = false
|
||||
return proxyReqOpts;
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
## Release Notes
|
||||
|
||||
| Release | Notes |
|
||||
| --- | --- |
|
||||
| 1.5.1 | Fixes bug in stringifying debug messages. |
|
||||
| 1.5.0 | Fixes bug in `filter` signature. Fix bug in skipToNextHandler, add expressHttpProxy value to user res when skipped. Add tests for host as ip address. |
|
||||
| 1.4.0 | DEPRECATED. Critical bug in the `filter` api.|
|
||||
| 1.3.0 | DEPRECATED. Critical bug in the `filter` api. `filter` now supports Promises. Update linter to eslint. |
|
||||
| 1.2.0 | Auto-stream when no decorations are made to req/res. Improved docs, fixes issues in maybeSkipToNexthandler, allow authors to manage error handling. |
|
||||
| 1.1.0 | Add step to allow response headers to be modified.
|
||||
| 1.0.7 | Update dependencies. Improve docs on promise rejection. Fix promise rejection on body limit. Improve debug output. |
|
||||
| 1.0.6 | Fixes preserveHostHdr not working, skip userResDecorator on 304, add maybeSkipToNext, test improvements and cleanup. |
|
||||
| 1.0.5 | Minor documentation and test patches |
|
||||
| 1.0.4 | Minor documentation, test, and package fixes |
|
||||
| 1.0.3 | Fixes 'limit option is not taken into account |
|
||||
| 1.0.2 | Minor docs corrections. |
|
||||
| 1.0.1 | Minor docs adjustments. |
|
||||
| 1.0.0 | Major revision. <br > REMOVE decorateRequest, ADD proxyReqOptDecorator and proxyReqBodyDecorator. <br /> REMOVE intercept, ADD userResDecorator <br /> userResDecorator supports a Promise form for async operations. <br /> General cleanup of structure and application of hooks. Documentation improvements. Update all dependencies. Re-organize code as a series of workflow steps, each (potentially) supporting a promise, and creating a reusable pattern for future development. |
|
||||
| 0.11.0 | Allow author to prevent host from being memoized between requests. General program cleanup. |
|
||||
| 0.10.1| Fixed issue where 'body encoding' was being incorrectly set to the character encoding. <br /> Dropped explicit support for node 0.10. <br /> Intercept can now deal with gziped responses. <br /> Author can now 'force https', even if the original request is over http. <br /> Do not call next after ECONNRESET catch. |
|
||||
| 0.10.0 | Fix regression in forwardPath implementation. |
|
||||
| 0.9.1 | Documentation updates. Set 'Accept-Encoding' header to match bodyEncoding. |
|
||||
| 0.9.0 | Better handling for request body when body is JSON. |
|
||||
| 0.8.0 | Features: add forwardPathAsync option <br />Updates: modernize dependencies <br />Fixes: Exceptions parsing proxied response causes error: Can't set headers after they are sent. (#111) <br />If client request aborts, proxied request is aborted too (#107) |
|
||||
| 0.7.4 | Move jscs to devDependencies to avoid conflict with nsp. |
|
||||
| 0.7.3 | Adds a timeout option. Code organization and small bug fixes. |
|
||||
| 0.7.2 | Collecting many minor documentation and test improvements. |
|
||||
| 0.4.0 | Signature of `intercept` callback changed from `function(data, req, res, callback)` to `function(rsp, data, req, res, callback)` where `rsp` is the original response from the target |
|
||||
|
||||
## Licence
|
||||
|
||||
MIT
|
||||
<!-- do not want to make nodeinit to complicated, you can edit this whenever you want. -->
|
||||
25
node_modules/express-http-proxy/app/steps/buildProxyReq.js
generated
vendored
Normal file
25
node_modules/express-http-proxy/app/steps/buildProxyReq.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
var requestOptions = require('../../lib/requestOptions');
|
||||
|
||||
function buildProxyReq(Container) {
|
||||
var req = Container.user.req;
|
||||
var res = Container.user.res;
|
||||
var options = Container.options;
|
||||
var host = Container.proxy.host;
|
||||
|
||||
var parseBody = (!options.parseReqBody) ? Promise.resolve(null) : requestOptions.bodyContent(req, res, options);
|
||||
var createReqOptions = requestOptions.create(req, res, options, host);
|
||||
|
||||
return Promise
|
||||
.all([parseBody, createReqOptions])
|
||||
.then(function(responseArray) {
|
||||
Container.proxy.bodyContent = responseArray[0];
|
||||
Container.proxy.reqBuilder = responseArray[1];
|
||||
debug('proxy request options:', Container.proxy.reqBuilder);
|
||||
return Container;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = buildProxyReq;
|
||||
22
node_modules/express-http-proxy/app/steps/copyProxyResHeadersToUserRes.js
generated
vendored
Normal file
22
node_modules/express-http-proxy/app/steps/copyProxyResHeadersToUserRes.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
function copyProxyResHeadersToUserRes(container) {
|
||||
return new Promise(function(resolve) {
|
||||
var res = container.user.res;
|
||||
var rsp = container.proxy.res;
|
||||
|
||||
if (!res.headersSent) {
|
||||
res.status(rsp.statusCode);
|
||||
Object.keys(rsp.headers)
|
||||
.filter(function(item) { return item !== 'transfer-encoding'; })
|
||||
.forEach(function(item) {
|
||||
res.set(item, rsp.headers[item]);
|
||||
});
|
||||
}
|
||||
|
||||
resolve(container);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = copyProxyResHeadersToUserRes;
|
||||
|
||||
25
node_modules/express-http-proxy/app/steps/decorateProxyReqBody.js
generated
vendored
Normal file
25
node_modules/express-http-proxy/app/steps/decorateProxyReqBody.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
function defaultDecorator(proxyReqOptBody/*, userReq */) {
|
||||
return proxyReqOptBody;
|
||||
}
|
||||
|
||||
function decorateProxyReqBody(container) {
|
||||
var userDecorator = container.options.proxyReqBodyDecorator;
|
||||
var resolverFn = userDecorator || defaultDecorator;
|
||||
|
||||
if (userDecorator) {
|
||||
debug('using custom proxyReqBodyDecorator');
|
||||
}
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(container.proxy.bodyContent, container.user.req))
|
||||
.then(function(bodyContent) {
|
||||
container.proxy.bodyContent = bodyContent;
|
||||
return Promise.resolve(container);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = decorateProxyReqBody;
|
||||
22
node_modules/express-http-proxy/app/steps/decorateProxyReqOpts.js
generated
vendored
Normal file
22
node_modules/express-http-proxy/app/steps/decorateProxyReqOpts.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
function defaultDecorator(proxyReqOptBuilder /*, userReq */) {
|
||||
return proxyReqOptBuilder;
|
||||
}
|
||||
|
||||
function decorateProxyReqOpt(container) {
|
||||
var resolverFn = container.options.proxyReqOptDecorator || defaultDecorator;
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(container.proxy.reqBuilder, container.user.req))
|
||||
.then(function (processedReqOpts) {
|
||||
delete processedReqOpts.params;
|
||||
container.proxy.reqBuilder = processedReqOpts;
|
||||
debug('Request options (after processing): %o', processedReqOpts);
|
||||
return Promise.resolve(container);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = decorateProxyReqOpt;
|
||||
66
node_modules/express-http-proxy/app/steps/decorateUserRes.js
generated
vendored
Normal file
66
node_modules/express-http-proxy/app/steps/decorateUserRes.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
var as = require('../../lib/as.js');
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
var zlib = require('zlib');
|
||||
|
||||
function isResGzipped(res) {
|
||||
return res.headers['content-encoding'] === 'gzip';
|
||||
}
|
||||
|
||||
function zipOrUnzip(method) {
|
||||
return function(rspData, res) {
|
||||
return (isResGzipped(res) && rspData.length) ? zlib[method](rspData) : rspData;
|
||||
};
|
||||
}
|
||||
|
||||
var maybeUnzipResponse = zipOrUnzip('gunzipSync');
|
||||
var maybeZipResponse = zipOrUnzip('gzipSync');
|
||||
|
||||
function verifyBuffer(rspd, reject) {
|
||||
if (!Buffer.isBuffer(rspd)) {
|
||||
return reject(new Error('userResDecorator should return string or buffer as data'));
|
||||
}
|
||||
}
|
||||
|
||||
function updateHeaders(res, rspdBefore, rspdAfter, reject) {
|
||||
if (!res.headersSent) {
|
||||
res.set('content-length', rspdAfter.length);
|
||||
} else if (rspdAfter.length !== rspdBefore.length) {
|
||||
var error = '"Content-Length" is already sent,' +
|
||||
'the length of response data can not be changed';
|
||||
return reject(new Error(error));
|
||||
}
|
||||
}
|
||||
|
||||
function decorateProxyResBody(container) {
|
||||
var resolverFn = container.options.userResDecorator;
|
||||
|
||||
if (!resolverFn) {
|
||||
return Promise.resolve(container);
|
||||
}
|
||||
|
||||
var proxyResData = maybeUnzipResponse(container.proxy.resData, container.proxy.res);
|
||||
var proxyRes = container.proxy.res;
|
||||
var req = container.user.req;
|
||||
var res = container.user.res;
|
||||
|
||||
if (res.statusCode === 304) {
|
||||
debug('Skipping userResDecorator on response 304');
|
||||
return Promise.resolve(container);
|
||||
}
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(proxyRes, proxyResData, req, res))
|
||||
.then(function(modifiedResData) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var rspd = as.buffer(modifiedResData, container.options);
|
||||
verifyBuffer(rspd, reject);
|
||||
updateHeaders(res, proxyResData, rspd, reject);
|
||||
container.proxy.resData = maybeZipResponse(rspd, container.proxy.res);
|
||||
resolve(container);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = decorateProxyResBody;
|
||||
22
node_modules/express-http-proxy/app/steps/decorateUserResHeaders.js
generated
vendored
Normal file
22
node_modules/express-http-proxy/app/steps/decorateUserResHeaders.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
function decorateUserResHeaders(container) {
|
||||
var resolverFn = container.options.userResHeaderDecorator;
|
||||
var headers = container.user.res._headers;
|
||||
|
||||
if (!resolverFn) {
|
||||
return Promise.resolve(container);
|
||||
}
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(headers, container.user.req, container.user.res, container.proxy.req, container.proxy.res))
|
||||
.then(function(headers) {
|
||||
return new Promise(function(resolve) {
|
||||
container.user.res.set(headers);
|
||||
resolve(container);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = decorateUserResHeaders;
|
||||
24
node_modules/express-http-proxy/app/steps/filterUserRequest.js
generated
vendored
Normal file
24
node_modules/express-http-proxy/app/steps/filterUserRequest.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
// No-op version of filter. Allows everything!
|
||||
|
||||
function defaultFilter(proxyReqOptBuilder, userReq) { // eslint-disable-line
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterUserRequest(container) {
|
||||
var resolverFn = container.options.filter || defaultFilter;
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(container.user.req, container.user.res))
|
||||
.then(function (shouldIContinue) {
|
||||
if (shouldIContinue) {
|
||||
return Promise.resolve(container);
|
||||
} else {
|
||||
return Promise.reject(); // reject with no args should simply call next()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = filterUserRequest;
|
||||
|
||||
21
node_modules/express-http-proxy/app/steps/handleProxyErrors.js
generated
vendored
Normal file
21
node_modules/express-http-proxy/app/steps/handleProxyErrors.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
function connectionResetHandler(err, res) {
|
||||
if (err && err.code === 'ECONNRESET') {
|
||||
debug('Error: Connection reset due to timeout.');
|
||||
res.setHeader('X-Timeout-Reason', 'express-http-proxy reset the request.');
|
||||
res.writeHead(504, {'Content-Type': 'text/plain'});
|
||||
res.end();
|
||||
}
|
||||
}
|
||||
|
||||
function handleProxyErrors(err, res, next) {
|
||||
switch (err && err.code) {
|
||||
case 'ECONNRESET': { return connectionResetHandler(err, res, next); }
|
||||
default: { next(err); }
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = handleProxyErrors;
|
||||
22
node_modules/express-http-proxy/app/steps/maybeSkipToNextHandler.js
generated
vendored
Normal file
22
node_modules/express-http-proxy/app/steps/maybeSkipToNextHandler.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
function defaultSkipFilter(/* res */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function maybeSkipToNextHandler(container) {
|
||||
var resolverFn = container.options.skipToNextHandlerFilter || defaultSkipFilter;
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(container.proxy.res))
|
||||
.then(function (shouldSkipToNext) {
|
||||
if (shouldSkipToNext) {
|
||||
container.user.res.expressHttpProxy = container.proxy;
|
||||
return Promise.reject(container.user.next());
|
||||
} else {
|
||||
return Promise.resolve(container);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = maybeSkipToNextHandler;
|
||||
40
node_modules/express-http-proxy/app/steps/prepareProxyReq.js
generated
vendored
Normal file
40
node_modules/express-http-proxy/app/steps/prepareProxyReq.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
var as = require('../../lib/as');
|
||||
|
||||
function getContentLength(body) {
|
||||
|
||||
var result;
|
||||
if (Buffer.isBuffer(body)) { // Buffer
|
||||
result = body.length;
|
||||
} else if (typeof body === 'string') {
|
||||
result = Buffer.byteLength(body);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function prepareProxyReq(container) {
|
||||
return new Promise(function(resolve) {
|
||||
var bodyContent = container.proxy.bodyContent;
|
||||
var reqOpt = container.proxy.reqBuilder;
|
||||
|
||||
if (bodyContent) {
|
||||
bodyContent = container.options.reqAsBuffer ?
|
||||
as.buffer(bodyContent, container.options) :
|
||||
as.bufferOrString(bodyContent);
|
||||
|
||||
reqOpt.headers['content-length'] = getContentLength(bodyContent);
|
||||
|
||||
if (container.options.reqBodyEncoding) {
|
||||
reqOpt.headers['Accept-Charset'] = container.options.reqBodyEncoding;
|
||||
}
|
||||
}
|
||||
|
||||
container.proxy.bodyContent = bodyContent;
|
||||
resolve(container);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = prepareProxyReq;
|
||||
|
||||
19
node_modules/express-http-proxy/app/steps/resolveProxyHost.js
generated
vendored
Normal file
19
node_modules/express-http-proxy/app/steps/resolveProxyHost.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
var requestOptions = require('../../lib/requestOptions');
|
||||
|
||||
function resolveProxyHost(container) {
|
||||
var parsedHost;
|
||||
|
||||
if (container.options.memoizeHost && container.options.memoizedHost) {
|
||||
parsedHost = container.options.memoizedHost;
|
||||
} else {
|
||||
parsedHost = requestOptions.parseHost(container);
|
||||
}
|
||||
|
||||
container.proxy.reqBuilder.host = parsedHost.host;
|
||||
container.proxy.reqBuilder.port = container.options.port || parsedHost.port;
|
||||
container.proxy.requestModule = parsedHost.module;
|
||||
return Promise.resolve(container);
|
||||
}
|
||||
|
||||
module.exports = resolveProxyHost;
|
||||
22
node_modules/express-http-proxy/app/steps/resolveProxyReqPath.js
generated
vendored
Normal file
22
node_modules/express-http-proxy/app/steps/resolveProxyReqPath.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var url = require('url');
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
function defaultProxyReqPathResolver(req) {
|
||||
return url.parse(req.url).path;
|
||||
}
|
||||
|
||||
function resolveProxyReqPath(container) {
|
||||
var resolverFn = container.options.proxyReqPathResolver || defaultProxyReqPathResolver;
|
||||
|
||||
return Promise
|
||||
.resolve(resolverFn(container.user.req))
|
||||
.then(function(resolvedPath) {
|
||||
container.proxy.reqBuilder.path = resolvedPath;
|
||||
debug('resolved proxy path:', resolvedPath);
|
||||
return Promise.resolve(container);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = resolveProxyReqPath;
|
||||
78
node_modules/express-http-proxy/app/steps/sendProxyRequest.js
generated
vendored
Normal file
78
node_modules/express-http-proxy/app/steps/sendProxyRequest.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
var chunkLength = require('../../lib/chunkLength');
|
||||
|
||||
function sendProxyRequest(Container) {
|
||||
var req = Container.user.req;
|
||||
var bodyContent = Container.proxy.bodyContent;
|
||||
var reqOpt = Container.proxy.reqBuilder;
|
||||
var options = Container.options;
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var protocol = Container.proxy.requestModule;
|
||||
var proxyReq = Container.proxy.req = protocol.request(reqOpt, function(rsp) {
|
||||
if (options.stream) {
|
||||
Container.proxy.res = rsp;
|
||||
return resolve(Container);
|
||||
}
|
||||
|
||||
var chunks = [];
|
||||
rsp.on('data', function(chunk) { chunks.push(chunk); });
|
||||
rsp.on('end', function() {
|
||||
Container.proxy.res = rsp;
|
||||
Container.proxy.resData = Buffer.concat(chunks, chunkLength(chunks));
|
||||
resolve(Container);
|
||||
});
|
||||
rsp.on('error', reject);
|
||||
});
|
||||
|
||||
proxyReq.on('socket', function(socket) {
|
||||
if (options.timeout) {
|
||||
socket.setTimeout(options.timeout, function() {
|
||||
proxyReq.abort();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
proxyReq.on('error', reject);
|
||||
|
||||
// this guy should go elsewhere, down the chain
|
||||
if (options.parseReqBody) {
|
||||
// We are parsing the body ourselves so we need to write the body content
|
||||
// and then manually end the request.
|
||||
|
||||
//if (bodyContent instanceof Object) {
|
||||
//throw new Error
|
||||
//debugger;
|
||||
//bodyContent = JSON.stringify(bodyContent);
|
||||
//}
|
||||
|
||||
if (bodyContent.length) {
|
||||
var body = bodyContent;
|
||||
var contentType = proxyReq.getHeader('Content-Type');
|
||||
if (contentType === 'x-www-form-urlencoded' || contentType === 'application/x-www-form-urlencoded') {
|
||||
try {
|
||||
var params = JSON.parse(body);
|
||||
body = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&');
|
||||
} catch (e) {
|
||||
// bodyContent is not json-format
|
||||
}
|
||||
}
|
||||
proxyReq.setHeader('Content-Length', Buffer.byteLength(body));
|
||||
proxyReq.write(body);
|
||||
}
|
||||
proxyReq.end();
|
||||
} else {
|
||||
// Pipe will call end when it has completely read from the request.
|
||||
req.pipe(proxyReq);
|
||||
}
|
||||
|
||||
req.on('aborted', function() {
|
||||
// reject?
|
||||
proxyReq.abort();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = sendProxyRequest;
|
||||
15
node_modules/express-http-proxy/app/steps/sendUserRes.js
generated
vendored
Normal file
15
node_modules/express-http-proxy/app/steps/sendUserRes.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
function sendUserRes(Container) {
|
||||
if (!Container.user.res.headersSent) {
|
||||
if (Container.options.stream) {
|
||||
Container.proxy.res.pipe(Container.user.res);
|
||||
} else {
|
||||
Container.user.res.send(Container.proxy.resData);
|
||||
}
|
||||
}
|
||||
return Promise.resolve(Container);
|
||||
}
|
||||
|
||||
|
||||
module.exports = sendUserRes;
|
||||
61
node_modules/express-http-proxy/index.js
generated
vendored
Normal file
61
node_modules/express-http-proxy/index.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
// * Breaks proxying into a series of discrete steps, many of which can be swapped out by authors.
|
||||
// * Uses Promises to support async.
|
||||
// * Uses a quasi-Global called Container to tidy up the argument passing between the major work-flow steps.
|
||||
|
||||
var ScopeContainer = require('./lib/scopeContainer');
|
||||
var assert = require('assert');
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
var buildProxyReq = require('./app/steps/buildProxyReq');
|
||||
var copyProxyResHeadersToUserRes = require('./app/steps/copyProxyResHeadersToUserRes');
|
||||
var decorateProxyReqBody = require('./app/steps/decorateProxyReqBody');
|
||||
var decorateProxyReqOpts = require('./app/steps/decorateProxyReqOpts');
|
||||
var decorateUserRes = require('./app/steps/decorateUserRes');
|
||||
var decorateUserResHeaders = require('./app/steps/decorateUserResHeaders');
|
||||
var filterUserRequest = require('./app/steps/filterUserRequest');
|
||||
var handleProxyErrors = require('./app/steps/handleProxyErrors');
|
||||
var maybeSkipToNextHandler = require('./app/steps/maybeSkipToNextHandler');
|
||||
var prepareProxyReq = require('./app/steps/prepareProxyReq');
|
||||
var resolveProxyHost = require('./app/steps/resolveProxyHost');
|
||||
var resolveProxyReqPath = require('./app/steps/resolveProxyReqPath');
|
||||
var sendProxyRequest = require('./app/steps/sendProxyRequest');
|
||||
var sendUserRes = require('./app/steps/sendUserRes');
|
||||
|
||||
module.exports = function proxy(host, userOptions) {
|
||||
assert(host, 'Host should not be empty');
|
||||
|
||||
return function handleProxy(req, res, next) {
|
||||
debug('[start proxy] ' + req.path);
|
||||
var container = new ScopeContainer(req, res, next, host, userOptions);
|
||||
|
||||
filterUserRequest(container)
|
||||
.then(buildProxyReq)
|
||||
.then(resolveProxyHost)
|
||||
.then(decorateProxyReqOpts)
|
||||
.then(resolveProxyReqPath)
|
||||
.then(decorateProxyReqBody)
|
||||
.then(prepareProxyReq)
|
||||
.then(sendProxyRequest)
|
||||
.then(maybeSkipToNextHandler)
|
||||
.then(copyProxyResHeadersToUserRes)
|
||||
.then(decorateUserResHeaders)
|
||||
.then(decorateUserRes)
|
||||
.then(sendUserRes)
|
||||
.catch(function (err) {
|
||||
// I sometimes reject without an error to shortcircuit the remaining
|
||||
// steps and return control to the host application.
|
||||
|
||||
if (err) {
|
||||
var resolver = (container.options.proxyErrorHandler) ?
|
||||
container.options.proxyErrorHandler :
|
||||
handleProxyErrors;
|
||||
resolver(err, res, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
36
node_modules/express-http-proxy/lib/as.js
generated
vendored
Normal file
36
node_modules/express-http-proxy/lib/as.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* Trivial convenience methods for parsing Buffers
|
||||
*/
|
||||
|
||||
function asBuffer(body, options) {
|
||||
|
||||
var ret;
|
||||
if (Buffer.isBuffer(body)) {
|
||||
ret = body;
|
||||
} else if (typeof body === 'object') {
|
||||
ret = new Buffer(JSON.stringify(body), options.reqBodyEncoding);
|
||||
} else if (typeof body === 'string') {
|
||||
ret = new Buffer(body, options.reqBodyEncodeing);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function asBufferOrString(body) {
|
||||
|
||||
var ret;
|
||||
if (Buffer.isBuffer(body)) {
|
||||
ret = body;
|
||||
} else if (typeof body === 'object') {
|
||||
ret = JSON.stringify(body);
|
||||
} else if (typeof body === 'string') {
|
||||
ret = body;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buffer: asBuffer,
|
||||
bufferOrString: asBufferOrString
|
||||
};
|
||||
9
node_modules/express-http-proxy/lib/chunkLength.js
generated
vendored
Normal file
9
node_modules/express-http-proxy/lib/chunkLength.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
function chunkLength(chunks) {
|
||||
return chunks.reduce(function (len, buf) {
|
||||
return len + buf.length;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
module.exports = chunkLength;
|
||||
5
node_modules/express-http-proxy/lib/isUnset.js
generated
vendored
Normal file
5
node_modules/express-http-proxy/lib/isUnset.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (val) {
|
||||
return (typeof val === 'undefined' || val === '' || val === null);
|
||||
};
|
||||
10
node_modules/express-http-proxy/lib/mockHTTP.js
generated
vendored
Normal file
10
node_modules/express-http-proxy/lib/mockHTTP.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
var app = require('express')();
|
||||
|
||||
app.use('/status/:status', function (req, res) {
|
||||
res.status(Number(req.params.status));
|
||||
res.send();
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
113
node_modules/express-http-proxy/lib/requestOptions.js
generated
vendored
Normal file
113
node_modules/express-http-proxy/lib/requestOptions.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var url = require('url');
|
||||
var getRawBody = require('raw-body');
|
||||
var isUnset = require('./isUnset');
|
||||
|
||||
function extend(obj, source, skips) {
|
||||
|
||||
if (!source) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
for (var prop in source) {
|
||||
if (!skips || skips.indexOf(prop) === -1) {
|
||||
obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function parseHost(Container) {
|
||||
var host = Container.params.host;
|
||||
var req = Container.user.req;
|
||||
var options = Container.options;
|
||||
host = (typeof host === 'function') ? host(req) : host.toString();
|
||||
|
||||
if (!host) {
|
||||
return new Error('Empty host parameter');
|
||||
}
|
||||
|
||||
if (!/http(s)?:\/\//.test(host)) {
|
||||
host = 'http://' + host;
|
||||
}
|
||||
|
||||
var parsed = url.parse(host);
|
||||
|
||||
if (!parsed.hostname) {
|
||||
return new Error('Unable to parse hostname, possibly missing protocol://?');
|
||||
}
|
||||
|
||||
var ishttps = options.https || parsed.protocol === 'https:';
|
||||
|
||||
return {
|
||||
host: parsed.hostname,
|
||||
port: parsed.port || (ishttps ? 443 : 80),
|
||||
module: ishttps ? https : http,
|
||||
};
|
||||
}
|
||||
|
||||
function reqHeaders(req, options) {
|
||||
|
||||
|
||||
var headers = options.headers || {};
|
||||
|
||||
var skipHdrs = [ 'connection', 'content-length' ];
|
||||
if (!options.preserveHostHdr) {
|
||||
skipHdrs.push('host');
|
||||
}
|
||||
var hds = extend(headers, req.headers, skipHdrs);
|
||||
hds.connection = 'close';
|
||||
|
||||
return hds;
|
||||
}
|
||||
|
||||
function createRequestOptions(req, res, options) {
|
||||
|
||||
// prepare proxyRequest
|
||||
|
||||
var reqOpt = {
|
||||
headers: reqHeaders(req, options),
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
params: req.params,
|
||||
};
|
||||
|
||||
if (options.preserveReqSession) {
|
||||
reqOpt.session = req.session;
|
||||
}
|
||||
|
||||
return Promise.resolve(reqOpt);
|
||||
}
|
||||
|
||||
// extract to bodyContent object
|
||||
|
||||
function bodyContent(req, res, options) {
|
||||
var parseReqBody = isUnset(options.parseReqBody) ? true : options.parseReqBody;
|
||||
|
||||
function maybeParseBody(req, limit) {
|
||||
if (req.body) {
|
||||
return Promise.resolve(req.body);
|
||||
} else {
|
||||
// Returns a promise if no callback specified and global Promise exists.
|
||||
|
||||
return getRawBody(req, {
|
||||
length: req.headers['content-length'],
|
||||
limit: limit,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (parseReqBody) {
|
||||
return maybeParseBody(req, options.limit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
create: createRequestOptions,
|
||||
bodyContent: bodyContent,
|
||||
parseHost: parseHost
|
||||
};
|
||||
79
node_modules/express-http-proxy/lib/resolveOptions.js
generated
vendored
Normal file
79
node_modules/express-http-proxy/lib/resolveOptions.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug')('express-http-proxy');
|
||||
|
||||
var isUnset = require('../lib/isUnset');
|
||||
|
||||
function resolveBodyEncoding(reqBodyEncoding) {
|
||||
|
||||
/* For reqBodyEncoding, these is a meaningful difference between null and
|
||||
* undefined. null should be passed forward as the value of reqBodyEncoding,
|
||||
* and undefined should result in utf-8.
|
||||
*/
|
||||
return reqBodyEncoding !== undefined ? reqBodyEncoding : 'utf-8';
|
||||
}
|
||||
|
||||
// parse client arguments
|
||||
|
||||
function resolveOptions(options) {
|
||||
options = options || {};
|
||||
var resolved;
|
||||
|
||||
if (options.decorateRequest) {
|
||||
throw new Error(
|
||||
'decorateRequest is REMOVED; use proxyReqOptDecorator and' +
|
||||
'proxyReqBodyDecorator instead. see README.md'
|
||||
);
|
||||
}
|
||||
|
||||
if (options.forwardPath || options.forwardPathAsync) {
|
||||
console.warn(
|
||||
'forwardPath and forwardPathAsync are DEPRECATED' +
|
||||
'and should be replaced with proxyReqPathResolver'
|
||||
);
|
||||
}
|
||||
|
||||
if (options.intercept) {
|
||||
console.warn(
|
||||
'DEPRECATED: intercept. Use decorateUseRes instead.' +
|
||||
' Please see README for more information.'
|
||||
);
|
||||
}
|
||||
|
||||
resolved = {
|
||||
limit: options.limit || '1mb',
|
||||
proxyReqPathResolver: options.proxyReqPathResolver
|
||||
|| options.forwardPathAsync
|
||||
|| options.forwardPath,
|
||||
proxyReqOptDecorator: options.proxyReqOptDecorator,
|
||||
proxyReqBodyDecorator: options.proxyReqBodyDecorator,
|
||||
userResDecorator: options.userResDecorator || options.intercept,
|
||||
userResHeaderDecorator: options.userResHeaderDecorator,
|
||||
proxyErrorHandler: options.proxyErrorHandler,
|
||||
filter: options.filter,
|
||||
// For backwards compatability, we default to legacy behavior for newly added settings.
|
||||
|
||||
parseReqBody: isUnset(options.parseReqBody) ? true : options.parseReqBody,
|
||||
preserveHostHdr: options.preserveHostHdr,
|
||||
memoizeHost: isUnset(options.memoizeHost) ? true : options.memoizeHost,
|
||||
reqBodyEncoding: resolveBodyEncoding(options.reqBodyEncoding),
|
||||
skipToNextHandlerFilter: options.skipToNextHandlerFilter,
|
||||
headers: options.headers,
|
||||
preserveReqSession: options.preserveReqSession,
|
||||
https: options.https,
|
||||
port: options.port,
|
||||
reqAsBuffer: options.reqAsBuffer,
|
||||
timeout: options.timeout
|
||||
};
|
||||
|
||||
// automatically opt into stream mode if no response modifiers are specified
|
||||
|
||||
resolved.stream = !resolved.skipToNextHandlerFilter &&
|
||||
!resolved.userResDecorator &&
|
||||
!resolved.userResHeaderDecorator;
|
||||
|
||||
debug(resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
module.exports = resolveOptions;
|
||||
35
node_modules/express-http-proxy/lib/scopeContainer.js
generated
vendored
Normal file
35
node_modules/express-http-proxy/lib/scopeContainer.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
var resolveOptions = require('../lib/resolveOptions');
|
||||
|
||||
// The Container object is passed down the chain of Promises, with each one
|
||||
// of them mutating and returning Container. The goal is that (eventually)
|
||||
// author using this library // could hook into/override any of these
|
||||
// workflow steps with a Promise or simple function.
|
||||
// Container for scoped arguments in a promise chain. Each promise recieves
|
||||
// this as its argument, and returns it.
|
||||
//
|
||||
// Do not expose the details of this to hooks/user functions.
|
||||
|
||||
function Container(req, res, next, host, userOptions) {
|
||||
return {
|
||||
user: {
|
||||
req: req,
|
||||
res: res,
|
||||
next: next,
|
||||
},
|
||||
proxy: {
|
||||
req: undefined,
|
||||
res: undefined,
|
||||
resData: undefined, // from proxy res
|
||||
bodyContent: undefined, // for proxy req
|
||||
reqBuilder: {}, // reqOpt, intended as first arg to http(s)?.request
|
||||
},
|
||||
options: resolveOptions(userOptions),
|
||||
params: {
|
||||
host: host,
|
||||
userOptions: userOptions
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Container;
|
||||
96
node_modules/express-http-proxy/package.json
generated
vendored
Normal file
96
node_modules/express-http-proxy/package.json
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"_from": "express-http-proxy",
|
||||
"_id": "express-http-proxy@1.5.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-k1RdysZWZ8wdPnsLa4iyrrYyUFih/sYKkn6WfkU/q5A8eUdh3l+oXhrRuQmEYEsZmiexVvpiOCkogl03jYfcbg==",
|
||||
"_location": "/express-http-proxy",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "express-http-proxy",
|
||||
"name": "express-http-proxy",
|
||||
"escapedName": "express-http-proxy",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/express-http-proxy/-/express-http-proxy-1.5.1.tgz",
|
||||
"_shasum": "cbf45695c759693c9c5f946117462d25b57e77a8",
|
||||
"_spec": "express-http-proxy",
|
||||
"_where": "D:\\dev\\crossmap\\backend-services\\cm-auth",
|
||||
"author": {
|
||||
"name": "villadora",
|
||||
"email": "jky239@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/villadora/express-http-proxy/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Liam Bennett"
|
||||
},
|
||||
{
|
||||
"name": "eldereal",
|
||||
"url": "https://github.com/eldereal"
|
||||
},
|
||||
{
|
||||
"name": "Saulius Menkevičius",
|
||||
"url": "https://github.com/razzmatazz"
|
||||
},
|
||||
{
|
||||
"name": "Jérémy Lal",
|
||||
"email": "kapouer@melix.org"
|
||||
},
|
||||
{
|
||||
"name": "Wei Gao",
|
||||
"email": "jky239@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nik Krimm",
|
||||
"url": "https://github.com/monkpow"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"debug": "^3.0.1",
|
||||
"es6-promise": "^4.1.1",
|
||||
"raw-body": "^2.3.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "http proxy middleware for express",
|
||||
"devDependencies": {
|
||||
"body-parser": "^1.17.2",
|
||||
"chai": "^4.1.2",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"eslint": "^4.19.1",
|
||||
"express": "^4.15.4",
|
||||
"mocha": "^5.2.0",
|
||||
"supertest": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/villadora/express-http-proxy#readme",
|
||||
"keywords": [
|
||||
"express-http-proxy"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "express-http-proxy",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/villadora/express-http-proxy.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint index.js **/*js",
|
||||
"mocha": "mocha -R spec test --recursive --exit",
|
||||
"test": "npm -s run mocha && npm run -s lint",
|
||||
"test:debug": "mocha debug -R spec test --recursive --exit"
|
||||
},
|
||||
"version": "1.5.1"
|
||||
}
|
||||
160
node_modules/express-http-proxy/test/bodyEncoding.js
generated
vendored
Normal file
160
node_modules/express-http-proxy/test/bodyEncoding.js
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
'use strict';
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var fs = require('fs');
|
||||
var os = require('os');
|
||||
var proxy = require('../');
|
||||
var startProxyTarget = require('./support/proxyTarget');
|
||||
|
||||
|
||||
describe('body encoding', function () {
|
||||
var server;
|
||||
|
||||
before(function () {
|
||||
server = startProxyTarget(8109, 1000);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
server.close();
|
||||
});
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var pngHex = '89504e470d0a1a0a0' +
|
||||
'000000d4948445200' +
|
||||
'00000100000001080' +
|
||||
'60000001f15c48900' +
|
||||
'00000a49444154789' +
|
||||
'c6300010000050001' +
|
||||
'0d0a2db4000000004' +
|
||||
'9454e44ae426082';
|
||||
var pngData = new Buffer(pngHex, 'hex');
|
||||
|
||||
it('allow raw data', function (done) {
|
||||
var filename = os.tmpdir() + '/express-http-proxy-test-' + (new Date()).getTime() + '-png-transparent.png';
|
||||
var app = express();
|
||||
|
||||
app.use(proxy('localhost:8109', {
|
||||
reqBodyEncoding: null,
|
||||
proxyReqBodyDecorator: function (bodyContent) {
|
||||
assert((new Buffer(bodyContent).toString('hex')).indexOf(pngData.toString('hex')) >= 0,
|
||||
'body should contain same data');
|
||||
return bodyContent;
|
||||
}
|
||||
}));
|
||||
|
||||
fs.writeFile(filename, pngData, function (err) {
|
||||
if (err) { throw err; }
|
||||
request(app)
|
||||
.post('/post')
|
||||
.attach('image', filename)
|
||||
.end(function (err) {
|
||||
fs.unlinkSync(filename);
|
||||
// This test is both broken and I think unnecessary.
|
||||
// Its broken because http.bin no longer supports /post, but this test assertion is based on the old
|
||||
// httpbin behavior.
|
||||
// The assertion in the decorateRequest above verifies the test title.
|
||||
//var response = new Buffer(res.body.attachment.data).toString('base64');
|
||||
//assert(response.indexOf(pngData.toString('base64')) >= 0, 'response should include original raw data');
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when user sets parseReqBody', function () {
|
||||
it('should not parse body', function (done) {
|
||||
var filename = os.tmpdir() + '/express-http-proxy-test-' + (new Date()).getTime() + '-png-transparent.png';
|
||||
var app = express();
|
||||
app.use(proxy('localhost:8109', {
|
||||
parseReqBody: false,
|
||||
proxyReqBodyDecorator: function (bodyContent) {
|
||||
assert(!bodyContent, 'body content should not be parsed.');
|
||||
return bodyContent;
|
||||
}
|
||||
}));
|
||||
|
||||
fs.writeFile(filename, pngData, function (err) {
|
||||
if (err) { throw err; }
|
||||
request(app)
|
||||
.post('/post')
|
||||
.attach('image', filename)
|
||||
.end(function (err) {
|
||||
fs.unlinkSync(filename);
|
||||
// This test is both broken and I think unnecessary.
|
||||
// Its broken because http.bin no longer supports /post, but this test assertion is based on the old
|
||||
// httpbin behavior.
|
||||
// The assertion in the decorateRequest above verifies the test title.
|
||||
// var response = new Buffer(res.body.attachment.data).toString('base64');
|
||||
// assert(response.indexOf(pngData.toString('base64')) >= 0, 'response should include original raw data');
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should not fail on large limit', function (done) {
|
||||
var filename = os.tmpdir() + '/express-http-proxy-test-' + (new Date()).getTime() + '-png-transparent.png';
|
||||
var app = express();
|
||||
app.use(proxy('localhost:8109', {
|
||||
parseReqBody: false,
|
||||
limit: '20gb',
|
||||
}));
|
||||
fs.writeFile(filename, pngData, function (err) {
|
||||
if (err) { throw err; }
|
||||
request(app)
|
||||
.post('/post')
|
||||
.attach('image', filename)
|
||||
.end(function (err) {
|
||||
fs.unlinkSync(filename);
|
||||
assert(err === null);
|
||||
// This test is both broken and I think unnecessary.
|
||||
// Its broken because http.bin no longer supports /post, but this test assertion is based on the old
|
||||
// httpbin behavior.
|
||||
// The assertion in the decorateRequest above verifies the test title.
|
||||
//var response = new Buffer(res.body.attachment.data).toString('base64');
|
||||
//assert(response.indexOf(pngData.toString('base64')) >= 0, 'response should include original raw data');
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should fail with an error when exceeding limit', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:8109', {
|
||||
limit: 1,
|
||||
}));
|
||||
// silence jshint warning about unused vars - express error handler *needs* 4 args
|
||||
app.use(function (err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
res.json(err);
|
||||
});
|
||||
request(app)
|
||||
.post('/post')
|
||||
.send({ some: 'json' })
|
||||
.end(function (err, response) {
|
||||
assert(response.body.message === 'request entity too large');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('when user sets reqBodyEncoding', function () {
|
||||
it('should set the accepts-charset header', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:8109', {
|
||||
reqBodyEncoding: 'utf-16'
|
||||
}));
|
||||
request(app)
|
||||
.get('/headers')
|
||||
.end(function (err, res) {
|
||||
if (err) { throw err; }
|
||||
assert.equal(res.body.headers['accept-charset'], 'utf-16');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
55
node_modules/express-http-proxy/test/catchingErrors.js
generated
vendored
Normal file
55
node_modules/express-http-proxy/test/catchingErrors.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('when server responds with an error', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var slowTarget;
|
||||
var serverReference;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
serverReference.close();
|
||||
});
|
||||
|
||||
var STATUS_CODES = [
|
||||
{ code: 403, text: 'Forbidden', toString: 'Error: cannot GET /proxy (403)' },
|
||||
{ code: 404, text: 'Not Found', toString: 'Error: cannot GET /proxy (404)' },
|
||||
{ code: 500, text: 'Internal Server Error', toString: 'Error: cannot GET /proxy (500)' }
|
||||
];
|
||||
|
||||
STATUS_CODES.forEach(function (statusCode) {
|
||||
it('express-http-proxy responds with ' + statusCode.text +
|
||||
'when proxy server responds ' + statusCode.code, function (done) {
|
||||
slowTarget = express();
|
||||
slowTarget.use(function (req, res) { res.sendStatus(statusCode.code); });
|
||||
serverReference = slowTarget.listen(12345);
|
||||
|
||||
app.use('/proxy', proxy('http://127.0.0.1:12345', {
|
||||
reqAsBuffer: true,
|
||||
reqBodyEncoding: null,
|
||||
parseReqBody: false
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/proxy')
|
||||
.expect(statusCode.code)
|
||||
.end(function (err, res) {
|
||||
assert(err === null);
|
||||
assert(res.error);
|
||||
assert(res.error.text === statusCode.text);
|
||||
assert(res.error.toString() === statusCode.toString);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
48
node_modules/express-http-proxy/test/cookies.js
generated
vendored
Normal file
48
node_modules/express-http-proxy/test/cookies.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/cookieTest',
|
||||
fn: function (req, res) {
|
||||
Object.keys(req.cookies).forEach(function (key) {
|
||||
res.cookie(key, req.cookies[key]);
|
||||
});
|
||||
res.sendStatus(200);
|
||||
}
|
||||
}];
|
||||
|
||||
describe('proxies cookie', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
app.use(proxy('localhost:12346'));
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
it('set cookie', function (done) {
|
||||
request(app)
|
||||
.get('/cookieTest')
|
||||
.set('Cookie', 'myApp-token=12345667')
|
||||
.end(function (err, res) {
|
||||
var cookiesMatch = res.headers['set-cookie'].filter(function (item) {
|
||||
return item.match(/myApp-token=12345667/);
|
||||
});
|
||||
assert(cookiesMatch);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
50
node_modules/express-http-proxy/test/decorateUserResHeaders.js
generated
vendored
Normal file
50
node_modules/express-http-proxy/test/decorateUserResHeaders.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('when userResHeaderDecorator is defined', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var serverReference;
|
||||
|
||||
afterEach(function () {
|
||||
serverReference.close();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
var pTarget = express();
|
||||
pTarget.use(function (req, res) { res.json(req.headers); });
|
||||
serverReference = pTarget.listen(12345);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
serverReference.close();
|
||||
});
|
||||
|
||||
it('provides an interface for updating headers', function (done) {
|
||||
|
||||
app.use('/proxy', proxy('http://127.0.0.1:12345', {
|
||||
userResHeaderDecorator: function (headers /*, userReq, userRes, proxyReq, proxyRes */) {
|
||||
headers.boltedonheader = 'franky';
|
||||
return headers;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/proxy')
|
||||
.expect(function (res) {
|
||||
assert(res.headers.boltedonheader === 'franky');
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
113
node_modules/express-http-proxy/test/filter.js
generated
vendored
Normal file
113
node_modules/express-http-proxy/test/filter.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/',
|
||||
fn: function (req, res) {
|
||||
return res.status(209).send('Proxy Server');
|
||||
}
|
||||
}];
|
||||
|
||||
function nextMethod(req, res, next) {
|
||||
res.status(201).send('Client Application');
|
||||
next();
|
||||
}
|
||||
|
||||
describe('filter', function () {
|
||||
var app = express();
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
describe('when filter function returns true', function () {
|
||||
it('continues route processing', function (done) {
|
||||
// should capture every possible path
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
filter: function () { return true; }
|
||||
}));
|
||||
|
||||
// because prior line should *always* fire and return, we should never get here.
|
||||
|
||||
app.use(nextMethod);
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(209)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when filter function returns false', function () {
|
||||
|
||||
it('hanldes route processing', function (done) {
|
||||
// should capture every possible path
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
filter: function () { return false; }
|
||||
}));
|
||||
|
||||
// because prior line should *always* fire skip, we should get here.
|
||||
|
||||
app.use(nextMethod);
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(201)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('promise form', function () {
|
||||
describe('when filter function returns true', function () {
|
||||
it('continues route processing', function (done) {
|
||||
// should capture every possible path
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
filter: function () { return new Promise(function (resolve) { resolve(true); }); }
|
||||
}));
|
||||
|
||||
// because prior line should *always* fire and return, we should never get here.
|
||||
|
||||
app.use(nextMethod);
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(209)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when filter function returns false', function () {
|
||||
|
||||
it('hanldes route processing', function (done) {
|
||||
// should capture every possible path
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
filter: function () { return new Promise(function (resolve) { resolve(false); }); }
|
||||
}));
|
||||
|
||||
// because prior line should *always* fire skip, we should get here.
|
||||
|
||||
app.use(nextMethod);
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(201)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
136
node_modules/express-http-proxy/test/handleProxyError.js
generated
vendored
Normal file
136
node_modules/express-http-proxy/test/handleProxyError.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/:errorCode',
|
||||
fn: function (req, res) {
|
||||
var errorCode = req.params.errorCode;
|
||||
if (errorCode === 'timeout') {
|
||||
return res.status(504).send('mock timeout');
|
||||
}
|
||||
return res.status(parseInt(errorCode)).send('test case error');
|
||||
}
|
||||
}];
|
||||
|
||||
describe('error handling can be over-ridden by user', function () {
|
||||
var app = express();
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
describe('when user provides a null function', function () {
|
||||
|
||||
describe('when author sets a timeout that fires', function () {
|
||||
it('passes 504 directly to client', function (done) {
|
||||
app.use(proxy('localhost:12346', {
|
||||
timeout: 1,
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/200')
|
||||
.expect(504)
|
||||
.expect('X-Timeout-Reason', 'express-http-proxy reset the request.')
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('passes status code (e.g. 504) directly to the client', function (done) {
|
||||
app.use(proxy('localhost:12346'));
|
||||
request(app)
|
||||
.get('/504')
|
||||
.expect(504)
|
||||
.expect(function (res) {
|
||||
assert(res.text === 'test case error');
|
||||
return res;
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('passes status code (e.g. 500) back to the client', function (done) {
|
||||
app.use(proxy('localhost:12346'));
|
||||
request(app)
|
||||
.get('/500')
|
||||
.expect(500)
|
||||
.end(function (err, res) {
|
||||
assert(res.text === 'test case error');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user provides a handler function', function () {
|
||||
var intentionallyWeirdStatusCode = 399;
|
||||
var intentionallyQuirkyStatusMessage = 'monkey skunky';
|
||||
|
||||
describe('when author sets a timeout that fires', function () {
|
||||
it('allows author to skip handling and handle in application step', function (done) {
|
||||
app.use(proxy('localhost:12346', {
|
||||
timeout: 1,
|
||||
proxyErrorHandler: function (err, res, next) {
|
||||
next(err);
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(function (err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
if (err.code === 'ECONNRESET') {
|
||||
res.status(intentionallyWeirdStatusCode).send(intentionallyQuirkyStatusMessage);
|
||||
}
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/200')
|
||||
.expect(function (res) {
|
||||
assert(res.text === intentionallyQuirkyStatusMessage);
|
||||
return res;
|
||||
})
|
||||
.expect(intentionallyWeirdStatusCode)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('allows authors to sub in their own handling', function (done) {
|
||||
app.use(proxy('localhost:12346', {
|
||||
timeout: 1,
|
||||
proxyErrorHandler: function (err, res, next) {
|
||||
switch (err && err.code) {
|
||||
case 'ECONNRESET': { return res.status(405).send('504 became 405'); }
|
||||
case 'ECONNREFUSED': { return res.status(200).send('gotcher back'); }
|
||||
default: { next(err); }
|
||||
}
|
||||
} }));
|
||||
|
||||
request(app)
|
||||
.get('/timeout')
|
||||
.expect(405)
|
||||
.expect(function (res) {
|
||||
assert(res.text === '504 became 405');
|
||||
return res;
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('passes status code (e.g. 500) back to the client', function (done) {
|
||||
app.use(proxy('localhost:12346'));
|
||||
request(app)
|
||||
.get('/500')
|
||||
.expect(500)
|
||||
.end(function (err, res) {
|
||||
assert(res.text === 'test case error');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
45
node_modules/express-http-proxy/test/headers.js
generated
vendored
Normal file
45
node_modules/express-http-proxy/test/headers.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('proxies headers', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var http;
|
||||
|
||||
beforeEach(function () {
|
||||
http = express();
|
||||
http.use(proxy('http://httpbin.org', {
|
||||
headers: {
|
||||
'X-Current-president': 'taft'
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
it('passed as options', function (done) {
|
||||
request(http)
|
||||
.get('/headers')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.body.headers['X-Current-President'] === 'taft');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('passed as on request', function (done) {
|
||||
request(http)
|
||||
.get('/headers')
|
||||
.set('X-Powerererer', 'XTYORG')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.body.headers['X-Powerererer']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
70
node_modules/express-http-proxy/test/host.js
generated
vendored
Normal file
70
node_modules/express-http-proxy/test/host.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('host can be a dynamic function', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app = express();
|
||||
describe('and memoization can be disabled', function () {
|
||||
var firstProxyApp = express();
|
||||
var secondProxyApp = express();
|
||||
// TODO: This seems like a bug factory. We will have intermittent port conflicts, yeah?
|
||||
|
||||
function randomNumberInPortRange() {
|
||||
return Math.floor(Math.random() * 48000) + 1024;
|
||||
}
|
||||
var firstPort = randomNumberInPortRange();
|
||||
var secondPort = randomNumberInPortRange();
|
||||
|
||||
var hostFn = function (req) {
|
||||
return 'localhost:' + req.params.port;
|
||||
};
|
||||
|
||||
app.use('/proxy/:port', proxy(hostFn, { memoizeHost: false }));
|
||||
|
||||
firstProxyApp
|
||||
.get('/', function (req, res) { res.sendStatus(204); })
|
||||
.listen(firstPort);
|
||||
|
||||
secondProxyApp
|
||||
.get('/', function (req, res) { res.sendStatus(200); })
|
||||
.listen(secondPort);
|
||||
|
||||
it('when not memoized, host resolves to a second value on the seecond call', function (done) {
|
||||
request(app)
|
||||
.get('/proxy/' + firstPort)
|
||||
.expect(204)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
request(app)
|
||||
.get('/proxy/' + secondPort)
|
||||
.expect(200, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('host can be an ip address', function () {
|
||||
it('with a port', function (done) {
|
||||
var app = express();
|
||||
app.use('/proxy/', proxy('127.0.0.1:3020'));
|
||||
|
||||
var targetApp = express();
|
||||
targetApp
|
||||
.get('/', function (req, res) { res.sendStatus(211); })
|
||||
.listen(3020);
|
||||
|
||||
|
||||
request(app)
|
||||
.get('/proxy/')
|
||||
.expect(211)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
59
node_modules/express-http-proxy/test/https.js
generated
vendored
Normal file
59
node_modules/express-http-proxy/test/https.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('proxies https', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
});
|
||||
|
||||
function assertSecureRequest(app, done) {
|
||||
request(app)
|
||||
.get('/get?show_env=1')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.body.headers['X-Forwarded-Port'] === '443', 'Expects forwarded 443 Port');
|
||||
assert(res.body.headers['X-Forwarded-Proto'] === 'https', 'Expects forwarded protocol to be https');
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
describe('when host is a String', function () {
|
||||
describe('and includes "https" as protocol', function () {
|
||||
it('proxys via https', function (done) {
|
||||
app.use(proxy('https://httpbin.org'));
|
||||
assertSecureRequest(app, done);
|
||||
});
|
||||
});
|
||||
describe('option https is set to "true"', function () {
|
||||
it('proxys via https', function (done) {
|
||||
app.use(proxy('http://httpbin.org', { https: true }));
|
||||
assertSecureRequest(app, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when host is a Function', function () {
|
||||
describe('returned value includes "https" as protocol', function () {
|
||||
it('proxys via https', function (done) {
|
||||
app.use(proxy(function () { return 'https://httpbin.org'; }));
|
||||
assertSecureRequest(app, done);
|
||||
});
|
||||
});
|
||||
describe('option https is set to "true"', function () {
|
||||
it('proxys via https', function (done) {
|
||||
app.use(proxy(function () { return 'http://httpbin.org'; }, { https: true }));
|
||||
assertSecureRequest(app, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
57
node_modules/express-http-proxy/test/maybeSkipToNextHandler.js
generated
vendored
Normal file
57
node_modules/express-http-proxy/test/maybeSkipToNextHandler.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var http = require('http');
|
||||
var assert = require('assert');
|
||||
|
||||
describe('when skipToNextHandlerFilter is defined', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var slowTarget;
|
||||
var serverReference;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
slowTarget = express();
|
||||
slowTarget.use(function (req, res) { res.sendStatus(404); });
|
||||
serverReference = slowTarget.listen(12345);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
serverReference.close();
|
||||
});
|
||||
|
||||
var OUTCOMES = [
|
||||
{ shouldSkip: true, expectedStatus: 200 },
|
||||
{ shouldSkip: false, expectedStatus: 404 }
|
||||
];
|
||||
|
||||
OUTCOMES.forEach(function (outcome) {
|
||||
describe('and returns ' + outcome.shouldSkip, function () {
|
||||
it('express-http-proxy' + (outcome.shouldSkip ? ' skips ' : ' doesnt skip ') + 'to next()', function (done) {
|
||||
|
||||
app.use('/proxy', proxy('http://127.0.0.1:12345', {
|
||||
skipToNextHandlerFilter: function (/*res*/) {
|
||||
return outcome.shouldSkip;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(function (req, res) {
|
||||
assert(res.expressHttpProxy instanceof Object);
|
||||
assert(res.expressHttpProxy.res instanceof http.IncomingMessage);
|
||||
assert(res.expressHttpProxy.req instanceof Object);
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/proxy')
|
||||
.expect(outcome.expectedStatus)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
110
node_modules/express-http-proxy/test/middlewareCompatibility.js
generated
vendored
Normal file
110
node_modules/express-http-proxy/test/middlewareCompatibility.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var bodyParser = require('body-parser');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
|
||||
|
||||
var proxyRouteFn = [{
|
||||
method: 'post',
|
||||
path: '/poster',
|
||||
fn: function (req, res) {
|
||||
res.send(req.body);
|
||||
}
|
||||
}];
|
||||
|
||||
describe('middleware compatibility', function () {
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
it('should use req.body if defined', function (done) {
|
||||
var app = express();
|
||||
|
||||
// Simulate another middleware that puts req stream into the body
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
var received = [];
|
||||
req.on('data', function onData(chunk) {
|
||||
if (!chunk) { return; }
|
||||
received.push(chunk);
|
||||
});
|
||||
req.on('end', function onEnd() {
|
||||
received = Buffer.concat(received).toString('utf8');
|
||||
req.body = JSON.parse(received);
|
||||
req.body.foo = 1;
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
app.use(proxy('localhost:12346', {
|
||||
intercept: function (rsp, data, req) {
|
||||
assert(req.body);
|
||||
assert.equal(req.body.foo, 1);
|
||||
assert.equal(req.body.mypost, 'hello');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.post('/poster')
|
||||
.send({ mypost: 'hello' })
|
||||
.expect(function (res) {
|
||||
assert.equal(res.body.foo, 1);
|
||||
assert.equal(res.body.mypost, 'hello');
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('should stringify req.body when it is a json body so it is written to proxy request', function (done) {
|
||||
var app = express();
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: false
|
||||
}));
|
||||
app.use(proxy('localhost:12346'));
|
||||
request(app)
|
||||
.post('/poster')
|
||||
.send({
|
||||
mypost: 'hello',
|
||||
doorknob: 'wrect'
|
||||
})
|
||||
.expect(function (res) {
|
||||
assert.equal(res.body.doorknob, 'wrect');
|
||||
assert.equal(res.body.mypost, 'hello');
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('should convert req.body to a Buffer when reqAsBuffer is set', function (done) {
|
||||
var app = express();
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: false
|
||||
}));
|
||||
app.use(proxy('localhost:12346', {
|
||||
reqAsBuffer: true
|
||||
}));
|
||||
request(app)
|
||||
.post('/poster')
|
||||
.send({
|
||||
mypost: 'hello',
|
||||
doorknob: 'wrect'
|
||||
})
|
||||
.expect(function (res) {
|
||||
assert.equal(res.body.doorknob, 'wrect');
|
||||
assert.equal(res.body.mypost, 'hello');
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
|
||||
});
|
||||
41
node_modules/express-http-proxy/test/params.js
generated
vendored
Normal file
41
node_modules/express-http-proxy/test/params.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/test',
|
||||
fn: function (req, res) {
|
||||
res.send(req.url);
|
||||
}
|
||||
}];
|
||||
|
||||
describe('proxies query parameters', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
app.use(proxy('localhost:12346'));
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
it('repeats query params to proxy server', function (done) {
|
||||
request(app)
|
||||
.get('/test?a=1&b=2&c=3')
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.text, '/test?a=1&b=2&c=3');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
95
node_modules/express-http-proxy/test/path.js
generated
vendored
Normal file
95
node_modules/express-http-proxy/test/path.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var startProxyTarget = require('./support/proxyTarget');
|
||||
var expect = require('chai').expect;
|
||||
|
||||
describe('uses remote path', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app = express();
|
||||
var proxyRoutes = ['/somePath/', '/somePath/longer/path', '/somePath/long/path/with/many/tokens'];
|
||||
var proxyKeyPath = '/somePath';
|
||||
var server;
|
||||
|
||||
afterEach(function () {
|
||||
server.close();
|
||||
});
|
||||
|
||||
proxyRoutes.forEach(function (path) {
|
||||
it('uses path component from inbound request', function (done) {
|
||||
|
||||
var modifiedPath = path.replace(new RegExp(proxyKeyPath), '');
|
||||
|
||||
var proxyRouteFn = {
|
||||
method: 'get',
|
||||
path: modifiedPath,
|
||||
fn: function (req, res) {
|
||||
res.json({ path: path, modifiedPath: modifiedPath });
|
||||
}
|
||||
};
|
||||
|
||||
server = startProxyTarget(8309, 1000, [proxyRouteFn]);
|
||||
|
||||
app.use('/somePath/', proxy('http://localhost:8309'));
|
||||
|
||||
request(app)
|
||||
.get(path)
|
||||
.expect(200)
|
||||
.end(function (err, response) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
expect(response.path === path);
|
||||
expect(response.modifiedPath === path);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('host can be a dynamic function', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app = express();
|
||||
var firstProxyApp = express();
|
||||
var secondProxyApp = express();
|
||||
var firstPort = 10031;
|
||||
var secondPort = 10032;
|
||||
|
||||
app.use('/proxy/:port', proxy(function (req) {
|
||||
return 'localhost:' + req.params.port;
|
||||
}, {
|
||||
memoizeHost: false
|
||||
}));
|
||||
|
||||
firstProxyApp.use('/', function (req, res) {
|
||||
res.sendStatus(204);
|
||||
});
|
||||
firstProxyApp.listen(firstPort);
|
||||
|
||||
secondProxyApp.use('/', function (req, res) {
|
||||
res.sendStatus(200);
|
||||
});
|
||||
secondProxyApp.listen(secondPort);
|
||||
|
||||
it('can proxy with session value', function (done) {
|
||||
request(app)
|
||||
.get('/proxy/' + firstPort)
|
||||
.expect(204)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
request(app)
|
||||
.get('/proxy/' + secondPort)
|
||||
.expect(200, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
84
node_modules/express-http-proxy/test/port.js
generated
vendored
Normal file
84
node_modules/express-http-proxy/test/port.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
function proxyTarget(port) {
|
||||
|
||||
var other = express();
|
||||
other.get('/', function (req, res) {
|
||||
res.send('Success');
|
||||
});
|
||||
return other.listen(port);
|
||||
}
|
||||
|
||||
describe('proxies to requested port', function () {
|
||||
var other;
|
||||
var http;
|
||||
|
||||
beforeEach(function () {
|
||||
http = express();
|
||||
other = proxyTarget(56001);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
other.close();
|
||||
});
|
||||
|
||||
|
||||
function assertSuccess(server, done) {
|
||||
request(http)
|
||||
.get('/')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.text === 'Success');
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
describe('when host is a String', function () {
|
||||
it('when passed as an option', function (done) {
|
||||
|
||||
http.use(proxy('http://localhost', {
|
||||
port: 56001
|
||||
}));
|
||||
|
||||
assertSuccess(http, done);
|
||||
});
|
||||
|
||||
it('when passed on the host string', function (done) {
|
||||
|
||||
http.use(proxy('http://localhost:56001'));
|
||||
|
||||
assertSuccess(http, done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when host is a function', function () {
|
||||
|
||||
|
||||
it('and port is on the String returned', function (done) {
|
||||
|
||||
http.use(proxy(
|
||||
function () { return 'http://localhost:56001'; }
|
||||
));
|
||||
|
||||
assertSuccess(http, done);
|
||||
});
|
||||
|
||||
it('and port passed as an option', function (done) {
|
||||
|
||||
http.use(proxy(
|
||||
function () { return 'http://localhost'; },
|
||||
{ port: 56001 }
|
||||
));
|
||||
|
||||
assertSuccess(http, done);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
65
node_modules/express-http-proxy/test/postBody.js
generated
vendored
Normal file
65
node_modules/express-http-proxy/test/postBody.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var bodyParser = require('body-parser');
|
||||
|
||||
|
||||
function createLocalApplicationServer() {
|
||||
var app = express();
|
||||
return app;
|
||||
}
|
||||
|
||||
function createProxyApplicationServer() {
|
||||
var pTarget = express();
|
||||
pTarget.use(bodyParser.json());
|
||||
pTarget.use(bodyParser.urlencoded({ extended: true }));
|
||||
pTarget.use(function (req, res) {
|
||||
assert(req.body.name === 'tobi'); //, 'Assert that the value posted to the local server is passed to the proxy');
|
||||
res.json(req.body);
|
||||
});
|
||||
return pTarget.listen(12345);
|
||||
}
|
||||
|
||||
describe('when proxy request is a POST', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var localServer;
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () {
|
||||
localServer = createLocalApplicationServer();
|
||||
proxyServer = createProxyApplicationServer();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
var testCases = [
|
||||
{ name: 'form encoded', encoding: 'application/x-www-form-urlencoded' },
|
||||
{ name: 'JSON encoded', encoding: 'application/json' }
|
||||
];
|
||||
|
||||
testCases.forEach(function (test) {
|
||||
it('should deliver the post body when ' + test.name, function (done) {
|
||||
|
||||
localServer.use('/proxy', proxy('http://127.0.0.1:12345'));
|
||||
localServer.use(function (req, res) { res.sendStatus(200); });
|
||||
localServer.use(function (err, req, res, next) { throw new Error(err, req, res, next); });
|
||||
|
||||
request(localServer)
|
||||
.post('/proxy')
|
||||
.send({ name: 'tobi' })
|
||||
.set('Content-Type', test.encoding)
|
||||
.expect(function (res) {
|
||||
assert(res.body.name === 'tobi');
|
||||
})
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
70
node_modules/express-http-proxy/test/preserveHostHdr.js
generated
vendored
Normal file
70
node_modules/express-http-proxy/test/preserveHostHdr.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/hostHdrTest',
|
||||
fn: function (req, res) {
|
||||
res.send(req.headers.host);
|
||||
}
|
||||
}];
|
||||
|
||||
describe('preserves host header only when requested', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var proxyServer;
|
||||
|
||||
describe('when preserveHostHdr is true', function () {
|
||||
before(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
app.use(proxy('localhost:12346', {
|
||||
preserveHostHdr: true
|
||||
}));
|
||||
});
|
||||
|
||||
after(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
it('host is passed forward', function (done) {
|
||||
request(app)
|
||||
.get('/hostHdrTest')
|
||||
.set('host', 'hamburger-helper')
|
||||
.end(function (err, res) {
|
||||
assert(res.text === 'hamburger-helper');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when preserveHostHdr is absent or false', function () {
|
||||
before(function () {
|
||||
proxyServer = proxyTarget(12346, 100, proxyRouteFn);
|
||||
app = express();
|
||||
app.use(proxy('localhost:12346'));
|
||||
});
|
||||
|
||||
after(function () {
|
||||
proxyServer.close();
|
||||
});
|
||||
|
||||
it('host is not passed forward', function (done) {
|
||||
request(app)
|
||||
.get('/hostHdrTest')
|
||||
.set('host', 'hamburger-helper')
|
||||
.end(function (err, res) {
|
||||
assert(res.text !== 'hamburger-helper');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
150
node_modules/express-http-proxy/test/proxyReqOptDecorator.js
generated
vendored
Normal file
150
node_modules/express-http-proxy/test/proxyReqOptDecorator.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var http = require('http');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
|
||||
describe('proxyReqOptDecorator', function () {
|
||||
var server;
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
before(function () {
|
||||
var handlers = [{
|
||||
method: 'get',
|
||||
path: '/working',
|
||||
fn: function (req, res) {
|
||||
res.send({ headers: req.headers });
|
||||
}
|
||||
}];
|
||||
|
||||
server = proxyTarget(12345, 100, handlers);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
server.close();
|
||||
});
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
app.use(proxy('localhost:12345'));
|
||||
});
|
||||
|
||||
describe('allows authors to modify a number of request parameters', function () {
|
||||
it('modify headers', function (done) {
|
||||
app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqOptDecorator: function (reqOpt) {
|
||||
reqOpt.headers['user-agent'] = 'test user agent';
|
||||
reqOpt.headers.mmmmmmmmmm = 'misty mountain hop';
|
||||
return reqOpt;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/working')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
|
||||
assert.equal(res.body.headers['user-agent'], 'test user agent');
|
||||
assert.equal(res.body.headers.mmmmmmmmmm, 'misty mountain hop');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when proxyReqOptDecorator is a simple function (non Promise)', function () {
|
||||
it('can modify headers', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqOptDecorator: function (reqOpt, req) {
|
||||
reqOpt.headers['user-agent'] = 'test user agent';
|
||||
assert(req instanceof http.IncomingMessage);
|
||||
return reqOpt;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/working')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert.equal(res.body.headers['user-agent'], 'test user agent');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when proxyReqOptDecorator is a Promise', function () {
|
||||
it('should mutate the proxied request', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqOptDecorator: function (reqOpt, req) {
|
||||
assert(req instanceof http.IncomingMessage);
|
||||
return new Promise(function (resolve) {
|
||||
reqOpt.headers['user-agent'] = 'test user agent';
|
||||
resolve(reqOpt);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/working')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert.equal(res.body.headers['user-agent'], 'test user agent');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the Promise is rejected', function () {
|
||||
it('returns err to host application for processing', function (done) {
|
||||
var app = express();
|
||||
|
||||
app.use(proxy('/reject-promise', {
|
||||
proxyReqOptDecorator: function () {
|
||||
return Promise.reject('An arbitrary rejection message.');
|
||||
}
|
||||
}));
|
||||
|
||||
/* jshint ignore:start */
|
||||
app.use(function (err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
assert(err === 'An arbitrary rejection message.');
|
||||
res.status(221).send(err);
|
||||
});
|
||||
/* jshint ignore:end */
|
||||
|
||||
request(app)
|
||||
.get('/reject-promise')
|
||||
.expect(221, done); // ensures we've entered the handler with assert above
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('proxyReqOptDecorator has access to the source request\'s data', function () {
|
||||
it('should have access to ip', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqOptDecorator: function (reqOpts, req) {
|
||||
assert(req instanceof http.IncomingMessage);
|
||||
assert(req.ip);
|
||||
return reqOpts;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/working')
|
||||
.end(function (err) {
|
||||
if (err) { return done(err); }
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
64
node_modules/express-http-proxy/test/proxyReqPathResolver.js
generated
vendored
Normal file
64
node_modules/express-http-proxy/test/proxyReqPathResolver.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var http = require('http');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
|
||||
var aliases = ['forwardPath', 'forwardPathAsync', 'proxyReqPathResolver'];
|
||||
|
||||
describe('resolveProxyReqPath', function () {
|
||||
var server;
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
before(function () {
|
||||
var handlers = [{
|
||||
method: 'get',
|
||||
path: '/working',
|
||||
fn: function (req, res) {
|
||||
res.sendStatus(200);
|
||||
}
|
||||
}];
|
||||
|
||||
server = proxyTarget(12345, 100, handlers);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
server.close();
|
||||
});
|
||||
|
||||
aliases.forEach(function (alias) {
|
||||
describe('when author uses option ' + alias, function () {
|
||||
it('the proxy request path is the result of the function', function (done) {
|
||||
var app = express();
|
||||
var opts = {};
|
||||
opts[alias] = function () { return '/working'; };
|
||||
app.use(proxy('localhost:12345', opts));
|
||||
|
||||
request(app)
|
||||
.get('/failing')
|
||||
.expect(200)
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('the ' + alias + ' method has access to request object', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
forwardPath: function (req) {
|
||||
assert.ok(req instanceof http.IncomingMessage);
|
||||
return '/working';
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/foobar')
|
||||
.expect(200)
|
||||
.end(done);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
116
node_modules/express-http-proxy/test/resolveProxyReqPath.js
generated
vendored
Normal file
116
node_modules/express-http-proxy/test/resolveProxyReqPath.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var ScopeContainer = require('../lib/scopeContainer');
|
||||
var resolveProxyReqPath = require('../app/steps/resolveProxyReqPath');
|
||||
var expect = require('chai').expect;
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
|
||||
describe('resolveProxyReqPath', function () {
|
||||
var container;
|
||||
|
||||
beforeEach(function () {
|
||||
container = new ScopeContainer();
|
||||
});
|
||||
|
||||
var tests = [
|
||||
{
|
||||
resolverType: 'undefined',
|
||||
resolverFn: undefined,
|
||||
data: [
|
||||
{ url: 'http://localhost:12345', parsed: '/' },
|
||||
{ url: 'http://g.com/123?45=67', parsed: '/123?45=67' }
|
||||
]
|
||||
},
|
||||
{
|
||||
resolverType: 'a syncronous function',
|
||||
resolverFn: function () { return 'the craziest thing'; },
|
||||
data: [
|
||||
{ url: 'http://localhost:12345', parsed: 'the craziest thing' },
|
||||
{ url: 'http://g.com/123?45=67', parsed: 'the craziest thing' }
|
||||
]
|
||||
},
|
||||
{
|
||||
resolverType: 'a Promise',
|
||||
resolverFn: function () {
|
||||
return new Promise(function (resolve) {
|
||||
resolve('the craziest think');
|
||||
});
|
||||
},
|
||||
data: [
|
||||
{ url: 'http://localhost:12345', parsed: 'the craziest think' },
|
||||
{ url: 'http://g.com/123?45=67', parsed: 'the craziest think' }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
describe('when proxyReqPathResolver', function () {
|
||||
|
||||
tests.forEach(function (test) {
|
||||
describe('is ' + test.resolverType, function () {
|
||||
describe('it returns a promise which resolves a container with expected url', function () {
|
||||
test.data.forEach(function (data) {
|
||||
it(data.url, function (done) {
|
||||
container.user.req = { url: data.url };
|
||||
container.options.proxyReqPathResolver = test.resolverFn;
|
||||
var r = resolveProxyReqPath(container);
|
||||
|
||||
assert(r instanceof Promise, 'Expect resolver to return a thennable');
|
||||
|
||||
r.then(function (container) {
|
||||
var response;
|
||||
try {
|
||||
response = container.proxy.reqBuilder.path;
|
||||
if (!response) {
|
||||
throw new Error('reqBuilder.url is undefined');
|
||||
}
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
expect(response).to.equal(data.parsed);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('testing example code in docs', function () {
|
||||
it('works as advertised', function (done) {
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/tent',
|
||||
fn: function (req, res) {
|
||||
res.send(req.url);
|
||||
}
|
||||
}];
|
||||
|
||||
var proxyServer = proxyTarget(12345, 100, proxyRouteFn);
|
||||
var app = express();
|
||||
app.use(proxy('localhost:12345', {
|
||||
proxyReqPathResolver: function (req) {
|
||||
var parts = req.url.split('?');
|
||||
var queryString = parts[1];
|
||||
var updatedPath = parts[0].replace(/test/, 'tent');
|
||||
return updatedPath + (queryString ? '?' + queryString : '');
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/test?a=1&b=2&c=3')
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.text, '/tent?a=1&b=2&c=3');
|
||||
proxyServer.close();
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
40
node_modules/express-http-proxy/test/session.js
generated
vendored
Normal file
40
node_modules/express-http-proxy/test/session.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('preserveReqSession', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
app.use(proxy('httpbin.org'));
|
||||
});
|
||||
|
||||
it('preserveReqSession', function (done) {
|
||||
var app = express();
|
||||
app.use(function (req, res, next) {
|
||||
req.session = 'hola';
|
||||
next();
|
||||
});
|
||||
app.use(proxy('httpbin.org', {
|
||||
preserveReqSession: true,
|
||||
proxyReqOptDecorator: function (reqOpts) {
|
||||
assert(reqOpts.session, 'hola');
|
||||
return reqOpts;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/user-agent')
|
||||
.end(function (err) {
|
||||
if (err) { return done(err); }
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
31
node_modules/express-http-proxy/test/status.js
generated
vendored
Normal file
31
node_modules/express-http-proxy/test/status.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var mockEndpoint = require('../lib/mockHTTP.js');
|
||||
|
||||
describe('proxies status code', function () {
|
||||
var proxyServer = express();
|
||||
var port = 21239;
|
||||
var proxiedEndpoint = 'http://localhost:' + port;
|
||||
var server;
|
||||
|
||||
proxyServer.use(proxy(proxiedEndpoint));
|
||||
|
||||
beforeEach(function () {
|
||||
server = mockEndpoint.listen(21239);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
server.close();
|
||||
});
|
||||
|
||||
[304, 404, 200, 401, 500].forEach(function (status) {
|
||||
it('on ' + status, function (done) {
|
||||
request(proxyServer)
|
||||
.get('/status/' + status)
|
||||
.expect(status, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
121
node_modules/express-http-proxy/test/streaming.js
generated
vendored
Normal file
121
node_modules/express-http-proxy/test/streaming.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var http = require('http');
|
||||
var startProxyTarget = require('./support/proxyTarget');
|
||||
var proxy = require('../');
|
||||
|
||||
function chunkingProxyServer() {
|
||||
var proxyRouteFn = [{
|
||||
method: 'get',
|
||||
path: '/stream',
|
||||
fn: function (req, res) {
|
||||
res.write('0');
|
||||
setTimeout(function () { res.write('1'); }, 100);
|
||||
setTimeout(function () { res.write('2'); }, 200);
|
||||
setTimeout(function () { res.write('3'); }, 300);
|
||||
setTimeout(function () { res.end(); }, 500);
|
||||
}
|
||||
}];
|
||||
|
||||
return startProxyTarget(8309, 1000, proxyRouteFn);
|
||||
}
|
||||
|
||||
function simulateUserRequest() {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var req = http.request({ hostname: 'localhost', port: 8308, path: '/stream' }, function (res) {
|
||||
var chunks = [];
|
||||
res.on('data', function (chunk) { chunks.push(chunk.toString()); });
|
||||
res.on('end', function () { resolve(chunks); });
|
||||
});
|
||||
|
||||
req.on('error', function (e) {
|
||||
reject('problem with request:', e.message);
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
function startLocalServer(proxyOptions) {
|
||||
var app = express();
|
||||
app.get('/stream', proxy('http://localhost:8309', proxyOptions));
|
||||
return app.listen(8308);
|
||||
}
|
||||
|
||||
describe('streams / piped requests', function () {
|
||||
this.timeout(3000);
|
||||
|
||||
var server;
|
||||
var targetServer;
|
||||
|
||||
beforeEach(function () {
|
||||
targetServer = chunkingProxyServer();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
server.close();
|
||||
targetServer.close();
|
||||
});
|
||||
|
||||
describe('when streaming options are truthy', function () {
|
||||
var TEST_CASES = [{
|
||||
name: 'vanilla, no options defined',
|
||||
options: {}
|
||||
}, {
|
||||
name: 'proxyReqOptDecorator is defined',
|
||||
options: { proxyReqOptDecorator: function (reqBuilder) { return reqBuilder; } }
|
||||
}, {
|
||||
//// Keep around this case for manually testing that this for sure fails for a few cycles. 2018 NMK
|
||||
//name: 'proxyReqOptDecorator never returns',
|
||||
//options: { proxyReqOptDecorator: function () { return new Promise(function () {}); } }
|
||||
//}, {
|
||||
|
||||
name: 'proxyReqOptDecorator is a Promise',
|
||||
options: { proxyReqOptDecorator: function (reqBuilder) { return Promise.resolve(reqBuilder); } }
|
||||
}];
|
||||
|
||||
TEST_CASES.forEach(function (testCase) {
|
||||
describe(testCase.name, function () {
|
||||
it('chunks are received without any buffering, e.g. before request end', function (done) {
|
||||
server = startLocalServer(testCase.options);
|
||||
simulateUserRequest()
|
||||
.then(function (res) {
|
||||
// Assume that if I'm getting a chunked response, it will be an array of length > 1;
|
||||
|
||||
assert(res instanceof Array, 'res is an Array');
|
||||
assert.equal(res.length, 4);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when streaming options are falsey', function () {
|
||||
var TEST_CASES = [{
|
||||
name: 'skipToNextHandler is defined',
|
||||
options: { skipToNextHandlerFilter: function () { return false; } }
|
||||
}];
|
||||
|
||||
TEST_CASES.forEach(function (testCase) {
|
||||
describe(testCase.name, function () {
|
||||
it('response arrives in one large chunk', function (done) {
|
||||
server = startLocalServer(testCase.options);
|
||||
|
||||
simulateUserRequest()
|
||||
.then(function (res) {
|
||||
// Assume that if I'm getting a un-chunked response, it will be an array of length = 1;
|
||||
|
||||
assert(res instanceof Array);
|
||||
assert.equal(res.length, 1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
55
node_modules/express-http-proxy/test/support/proxyTarget.js
generated
vendored
Normal file
55
node_modules/express-http-proxy/test/support/proxyTarget.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var cookieParser = require('cookie-parser');
|
||||
|
||||
function proxyTarget(port, timeout, handlers) {
|
||||
var target = express();
|
||||
|
||||
timeout = timeout || 100;
|
||||
|
||||
// parse application/x-www-form-urlencoded
|
||||
target.use(bodyParser.urlencoded({ extended: false }));
|
||||
|
||||
// parse application/json
|
||||
target.use(bodyParser.json());
|
||||
target.use(cookieParser());
|
||||
|
||||
target.use(function(req, res, next) {
|
||||
setTimeout(function() {
|
||||
next();
|
||||
},timeout);
|
||||
});
|
||||
|
||||
if (handlers) {
|
||||
handlers.forEach(function(handler) {
|
||||
target[handler.method](handler.path, handler.fn);
|
||||
});
|
||||
}
|
||||
|
||||
target.get('/get', function (req, res) {
|
||||
res.send('OK');
|
||||
});
|
||||
|
||||
target.post('/post', function(req, res) {
|
||||
req.pipe(res);
|
||||
});
|
||||
|
||||
target.use('/headers', function(req, res) {
|
||||
res.json({ headers: req.headers });
|
||||
});
|
||||
|
||||
target.use(function(err, req, res, next) {
|
||||
res.send(err);
|
||||
next();
|
||||
});
|
||||
|
||||
target.use(function(req, res) {
|
||||
res.sendStatus(404);
|
||||
});
|
||||
|
||||
return target.listen(port);
|
||||
}
|
||||
|
||||
module.exports = proxyTarget;
|
||||
63
node_modules/express-http-proxy/test/timeout.js
generated
vendored
Normal file
63
node_modules/express-http-proxy/test/timeout.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('./support/proxyTarget');
|
||||
|
||||
describe('honors timeout option', function () {
|
||||
|
||||
var other;
|
||||
var http;
|
||||
|
||||
beforeEach(function () {
|
||||
http = express();
|
||||
other = proxyTarget(56001, 1000, [{
|
||||
method: 'get',
|
||||
path: '/',
|
||||
fn: function (req, res) { res.sendStatus(200); }
|
||||
}]);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
other.close();
|
||||
});
|
||||
|
||||
function assertSuccess(server, done) {
|
||||
request(http)
|
||||
.get('/')
|
||||
.expect(200)
|
||||
.end(done);
|
||||
}
|
||||
|
||||
function assertConnectionTimeout(server, done) {
|
||||
request(http)
|
||||
.get('/')
|
||||
.expect(504)
|
||||
.expect('X-Timeout-Reason', 'express-http-proxy reset the request.')
|
||||
.end(done);
|
||||
}
|
||||
|
||||
describe('when timeout option is set lower than server response time', function () {
|
||||
it('should fail with CONNECTION TIMEOUT', function (done) {
|
||||
|
||||
http.use(proxy('http://localhost:56001', {
|
||||
timeout: 100,
|
||||
}));
|
||||
|
||||
assertConnectionTimeout(http, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when timeout option is set higher than server response time', function () {
|
||||
it('should succeed', function (done) {
|
||||
|
||||
http.use(proxy('http://localhost:56001', {
|
||||
timeout: 1200,
|
||||
}));
|
||||
|
||||
assertSuccess(http, done);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
41
node_modules/express-http-proxy/test/traceDebugging.js
generated
vendored
Normal file
41
node_modules/express-http-proxy/test/traceDebugging.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
var debug = require('debug');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
var proxyTarget = require('../test/support/proxyTarget');
|
||||
|
||||
/* This test is specifically written because of critical errors thrown while debug logging. */
|
||||
describe.only('trace debugging does not cause the application to fail', function () {
|
||||
var proxyServer;
|
||||
|
||||
beforeEach(function () { debug.enable('express-http-proxy'); proxyServer = proxyTarget(3000); });
|
||||
afterEach(function () { debug.disable('express-http-proxy'); proxyServer.close(); });
|
||||
|
||||
it('happy path', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('localhost:3000'));
|
||||
request(app)
|
||||
.get('/get')
|
||||
.expect(200)
|
||||
.end(done);
|
||||
});
|
||||
|
||||
it('when agent is a deeply nested object', function (done) {
|
||||
var app = express();
|
||||
var HttpAgent = require('http').Agent;
|
||||
var httpAgent = new HttpAgent({ keepAlive: true, keepAliveMsecs: 60e3 });
|
||||
app.use(proxy('localhost:3000', {
|
||||
proxyReqOptDecorator: function (proxyReqOpts) {
|
||||
proxyReqOpts.agent = httpAgent;
|
||||
return proxyReqOpts;
|
||||
}
|
||||
}));
|
||||
request(app)
|
||||
.get('/get')
|
||||
.expect(200)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
37
node_modules/express-http-proxy/test/urlParsing.js
generated
vendored
Normal file
37
node_modules/express-http-proxy/test/urlParsing.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('url parsing', function () {
|
||||
|
||||
this.timeout(10000);
|
||||
|
||||
it('can parse a url with a port', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('http://httpbin.org:80'));
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function (err) {
|
||||
if (err) { return done(err); }
|
||||
assert(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not throw `Uncaught RangeError` if you have both a port and a trailing slash', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('http://httpbin.org:80/'));
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function (err) {
|
||||
if (err) { return done(err); }
|
||||
assert(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
213
node_modules/express-http-proxy/test/userResDecorator.js
generated
vendored
Normal file
213
node_modules/express-http-proxy/test/userResDecorator.js
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('userResDecorator', function () {
|
||||
|
||||
describe('when handling a 304', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
var slowTarget;
|
||||
var serverReference;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
slowTarget = express();
|
||||
slowTarget.use(function (req, res) { res.sendStatus(304); });
|
||||
serverReference = slowTarget.listen(12345);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
serverReference.close();
|
||||
});
|
||||
|
||||
it('skips any handling', function (done) {
|
||||
app.use('/proxy', proxy('http://127.0.0.1:12345', {
|
||||
userResDecorator: function (/*res*/) {
|
||||
throw new Error('expected to never get here because this step should be skipped for 304');
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/proxy')
|
||||
.expect(304)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('has access to original response', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function (proxyRes, proxyResData) {
|
||||
assert(proxyRes.connection);
|
||||
assert(proxyRes.socket);
|
||||
assert(proxyRes.headers);
|
||||
assert(proxyRes.headers['content-type']);
|
||||
return proxyResData;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app).get('/').end(done);
|
||||
});
|
||||
|
||||
it('works with promises', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function (proxyRes, proxyResData) {
|
||||
return new Promise(function (resolve) {
|
||||
proxyResData.funkyMessage = 'oi io oo ii';
|
||||
setTimeout(function () {
|
||||
resolve(proxyResData);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/ip')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
|
||||
assert(res.body.funkyMessage = 'oi io oo ii');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('can modify the response data', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function (proxyRes, proxyResData) {
|
||||
proxyResData = JSON.parse(proxyResData.toString('utf8'));
|
||||
proxyResData.intercepted = true;
|
||||
return JSON.stringify(proxyResData);
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/ip')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
|
||||
assert(res.body.intercepted);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('can modify the response headers, [deviant case, supported by pass-by-reference atm]', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function (rsp, data, req, res) {
|
||||
res.set('x-wombat-alliance', 'mammels');
|
||||
res.set('content-type', 'wiki/wiki');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/ip')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.headers['content-type'] === 'wiki/wiki');
|
||||
assert(res.headers['x-wombat-alliance'] === 'mammels');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can mutuate an html response', function (done) {
|
||||
var app = express();
|
||||
app.use(proxy('httpbin.org', {
|
||||
userResDecorator: function (rsp, data) {
|
||||
data = data.toString().replace('Oh', '<strong>Hey</strong>');
|
||||
assert(data !== '');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/html')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.text.indexOf('<strong>Hey</strong>') > -1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can change the location of a redirect', function (done) {
|
||||
|
||||
function redirectingServer(port, origin) {
|
||||
var app = express();
|
||||
app.get('/', function (req, res) {
|
||||
res.status(302);
|
||||
res.location(origin + '/proxied/redirect/url');
|
||||
res.send();
|
||||
});
|
||||
return app.listen(port);
|
||||
}
|
||||
|
||||
var redirectingServerPort = 8012;
|
||||
var redirectingServerOrigin = ['http://localhost', redirectingServerPort].join(':');
|
||||
|
||||
var server = redirectingServer(redirectingServerPort, redirectingServerOrigin);
|
||||
|
||||
var proxyApp = express();
|
||||
var preferredPort = 3000;
|
||||
|
||||
proxyApp.use(proxy(redirectingServerOrigin, {
|
||||
userResDecorator: function (rsp, data, req, res) {
|
||||
var proxyReturnedLocation = res._headers.location;
|
||||
res.location(proxyReturnedLocation.replace(redirectingServerPort, preferredPort));
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
|
||||
request(proxyApp)
|
||||
.get('/')
|
||||
.expect(function (res) {
|
||||
res.headers.location.match(/localhost:3000/);
|
||||
})
|
||||
.end(function () {
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('test userResDecorator on html response from github', function () {
|
||||
|
||||
/*
|
||||
Github provided a unique situation where the encoding was different than
|
||||
utf-8 when we didn't explicitly ask for utf-8. This test helped sort out
|
||||
the issue, and even though its a little too on the nose for a specific
|
||||
case, it seems worth keeping around to ensure we don't regress on this
|
||||
issue.
|
||||
*/
|
||||
|
||||
it('is able to read and manipulate the response', function (done) {
|
||||
this.timeout(15000); // give it some extra time to get response
|
||||
var app = express();
|
||||
app.use(proxy('https://github.com/villadora/express-http-proxy', {
|
||||
userResDecorator: function (targetResponse, data) {
|
||||
data = data.toString().replace('DOCTYPE', 'WINNING');
|
||||
assert(data !== '');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
|
||||
request(app)
|
||||
.get('/html')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(res.text.indexOf('WINNING') > -1);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
90
node_modules/express-http-proxy/test/verbs.js
generated
vendored
Normal file
90
node_modules/express-http-proxy/test/verbs.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var request = require('supertest');
|
||||
var proxy = require('../');
|
||||
|
||||
describe('http verbs', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var app;
|
||||
|
||||
beforeEach(function () {
|
||||
app = express();
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(proxy('httpbin.org'));
|
||||
});
|
||||
|
||||
it('test proxy get', function (done) {
|
||||
request(app)
|
||||
.get('/get')
|
||||
.end(function (err, res) {
|
||||
if (err) { return done(err); }
|
||||
assert(/node-superagent/.test(res.body.headers['User-Agent']));
|
||||
assert.equal(res.body.url, 'http://httpbin.org/get');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('test proxy post', function (done) {
|
||||
request(app)
|
||||
.post('/post')
|
||||
.send({
|
||||
mypost: 'hello'
|
||||
})
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.body.data, '{"mypost":"hello"}');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('test proxy post by x-www-form-urlencoded', function (done) {
|
||||
request(app)
|
||||
.post('/post')
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
.send('mypost=hello')
|
||||
.end(function (err, res) {
|
||||
assert.equal(JSON.stringify(res.body.form), '{"mypost":"hello"}');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('test proxy put', function (done) {
|
||||
request(app)
|
||||
.put('/put')
|
||||
.send({
|
||||
mypost: 'hello'
|
||||
})
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.body.data, '{"mypost":"hello"}');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('test proxy patch', function (done) {
|
||||
request(app)
|
||||
.patch('/patch')
|
||||
.send({
|
||||
mypost: 'hello'
|
||||
})
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.body.data, '{"mypost":"hello"}');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('test proxy delete', function (done) {
|
||||
request(app)
|
||||
.del('/delete')
|
||||
.send({
|
||||
mypost: 'hello'
|
||||
})
|
||||
.end(function (err, res) {
|
||||
assert.equal(res.body.data, '{"mypost":"hello"}');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user