mirror of
https://github.com/LukeHagar/arbiter.git
synced 2025-12-09 12:27:48 +00:00
Saving all progress
This commit is contained in:
22
node_modules/http-proxy-middleware/LICENSE
generated
vendored
Normal file
22
node_modules/http-proxy-middleware/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Steven Chim
|
||||
|
||||
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.
|
||||
|
||||
648
node_modules/http-proxy-middleware/README.md
generated
vendored
Normal file
648
node_modules/http-proxy-middleware/README.md
generated
vendored
Normal file
@@ -0,0 +1,648 @@
|
||||
# http-proxy-middleware
|
||||
|
||||
[](https://github.com/chimurai/http-proxy-middleware/actions/workflows/ci.yml?query=branch%3Amaster)
|
||||
[](https://coveralls.io/r/chimurai/http-proxy-middleware)
|
||||
[](https://snyk.io/test/github/chimurai/http-proxy-middleware)
|
||||
[](https://www.npmjs.com/package/http-proxy-middleware)
|
||||
|
||||
Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/expressjs/express), [next.js](https://github.com/vercel/next.js) and [many more](#compatible-servers).
|
||||
|
||||
Powered by the popular Nodejitsu [`http-proxy`](https://github.com/http-party/node-http-proxy). [](https://github.com/http-party/node-http-proxy)
|
||||
|
||||
## ⚠️ Note <!-- omit in toc -->
|
||||
|
||||
This page is showing documentation for version v3.x.x ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
|
||||
|
||||
See [MIGRATION.md](https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md) for details on how to migrate from v2.x.x to v3.x.x
|
||||
|
||||
If you're looking for older documentation. Go to:
|
||||
|
||||
- <https://github.com/chimurai/http-proxy-middleware/tree/v2.0.4#readme>
|
||||
- <https://github.com/chimurai/http-proxy-middleware/tree/v0.21.0#readme>
|
||||
|
||||
## TL;DR <!-- omit in toc -->
|
||||
|
||||
Proxy `/api` requests to `http://www.example.org`
|
||||
|
||||
:bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
|
||||
|
||||
```typescript
|
||||
// typescript
|
||||
|
||||
import * as express from 'express';
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
|
||||
import { createProxyMiddleware } from 'http-proxy-middleware';
|
||||
import type { Filter, Options, RequestHandler } from 'http-proxy-middleware';
|
||||
|
||||
const app = express();
|
||||
|
||||
const proxyMiddleware = createProxyMiddleware<Request, Response>({
|
||||
target: 'http://www.example.org/api',
|
||||
changeOrigin: true,
|
||||
}),
|
||||
|
||||
app.use('/api', proxyMiddleware);
|
||||
|
||||
app.listen(3000);
|
||||
|
||||
// proxy and keep the same base path "/api"
|
||||
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar
|
||||
|
||||
```
|
||||
|
||||
_All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#options) can be used, along with some extra `http-proxy-middleware` [options](#options).
|
||||
|
||||
## Table of Contents <!-- omit in toc -->
|
||||
|
||||
<!-- // spell-checker:disable -->
|
||||
|
||||
- [Install](#install)
|
||||
- [Basic usage](#basic-usage)
|
||||
- [Express Server Example](#express-server-example)
|
||||
- [app.use(path, proxy)](#appusepath-proxy)
|
||||
- [Options](#options)
|
||||
- [`pathFilter` (string, \[\]string, glob, \[\]glob, function)](#pathfilter-string-string-glob-glob-function)
|
||||
- [`pathRewrite` (object/function)](#pathrewrite-objectfunction)
|
||||
- [`router` (object/function)](#router-objectfunction)
|
||||
- [`plugins` (Array)](#plugins-array)
|
||||
- [`ejectPlugins` (boolean) default: `false`](#ejectplugins-boolean-default-false)
|
||||
- [`logger` (Object)](#logger-object)
|
||||
- [`http-proxy` events](#http-proxy-events)
|
||||
- [`http-proxy` options](#http-proxy-options)
|
||||
- [WebSocket](#websocket)
|
||||
- [External WebSocket upgrade](#external-websocket-upgrade)
|
||||
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
|
||||
- [Intercept and manipulate responses](#intercept-and-manipulate-responses)
|
||||
- [Node.js 17+: ECONNREFUSED issue with IPv6 and localhost (#705)](#nodejs-17-econnrefused-issue-with-ipv6-and-localhost-705)
|
||||
- [Debugging](#debugging)
|
||||
- [Working examples](#working-examples)
|
||||
- [Recipes](#recipes)
|
||||
- [Compatible servers](#compatible-servers)
|
||||
- [Tests](#tests)
|
||||
- [Changelog](#changelog)
|
||||
- [License](#license)
|
||||
|
||||
<!-- // spell-checker:enable -->
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
npm install --save-dev http-proxy-middleware
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
|
||||
|
||||
```javascript
|
||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
|
||||
const apiProxy = createProxyMiddleware({
|
||||
target: 'http://www.example.org',
|
||||
changeOrigin: true,
|
||||
});
|
||||
|
||||
// 'apiProxy' is now ready to be used as middleware in a server.
|
||||
```
|
||||
|
||||
- **options.target**: target host to proxy to. _(protocol + host)_
|
||||
- **options.changeOrigin**: for virtual hosted sites
|
||||
|
||||
- see full list of [`http-proxy-middleware` configuration options](#options)
|
||||
|
||||
## Express Server Example
|
||||
|
||||
An example with `express` server.
|
||||
|
||||
```javascript
|
||||
// include dependencies
|
||||
const express = require('express');
|
||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
|
||||
const app = express();
|
||||
|
||||
// create the proxy
|
||||
/** @type {import('http-proxy-middleware/dist/types').RequestHandler<express.Request, express.Response>} */
|
||||
const exampleProxy = createProxyMiddleware({
|
||||
target: 'http://www.example.org/api', // target host with the same base path
|
||||
changeOrigin: true, // needed for virtual hosted sites
|
||||
});
|
||||
|
||||
// mount `exampleProxy` in web server
|
||||
app.use('/api', exampleProxy);
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
### app.use(path, proxy)
|
||||
|
||||
If you want to use the server's `app.use` `path` parameter to match requests.
|
||||
Use `pathFilter` option to further include/exclude requests which you want to proxy.
|
||||
|
||||
```javascript
|
||||
app.use(
|
||||
createProxyMiddleware({
|
||||
target: 'http://www.example.org/api',
|
||||
changeOrigin: true,
|
||||
pathFilter: '/api/proxy-only-this-path',
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
`app.use` documentation:
|
||||
|
||||
- express: <http://expressjs.com/en/4x/api.html#app.use>
|
||||
- connect: <https://github.com/senchalabs/connect#mount-middleware>
|
||||
- polka: <https://github.com/lukeed/polka#usebase-fn>
|
||||
|
||||
## Options
|
||||
|
||||
http-proxy-middleware options:
|
||||
|
||||
### `pathFilter` (string, []string, glob, []glob, function)
|
||||
|
||||
Narrow down which requests should be proxied. The `path` used for filtering is the `request.url` pathname. In Express, this is the `path` relative to the mount-point of the proxy.
|
||||
|
||||
- **path matching**
|
||||
|
||||
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied when `pathFilter` is not configured.
|
||||
- `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
|
||||
|
||||
- **multiple path matching**
|
||||
|
||||
- `createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})`
|
||||
|
||||
- **wildcard path matching**
|
||||
|
||||
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
|
||||
|
||||
- `createProxyMiddleware({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
|
||||
- `createProxyMiddleware({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
|
||||
- `createProxyMiddleware({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
|
||||
- `createProxyMiddleware({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
|
||||
- `createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
|
||||
- `createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...})` exclusion
|
||||
|
||||
**Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
|
||||
|
||||
- **custom matching**
|
||||
|
||||
For full control you can provide a custom function to determine which requests should be proxied or not.
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @return {Boolean}
|
||||
*/
|
||||
const pathFilter = function (path, req) {
|
||||
return path.match('^/api') && req.method === 'GET';
|
||||
};
|
||||
|
||||
const apiProxy = createProxyMiddleware({
|
||||
target: 'http://www.example.org',
|
||||
pathFilter: pathFilter,
|
||||
});
|
||||
```
|
||||
|
||||
### `pathRewrite` (object/function)
|
||||
|
||||
Rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
|
||||
|
||||
```javascript
|
||||
// rewrite path
|
||||
pathRewrite: {'^/old/api' : '/new/api'}
|
||||
|
||||
// remove path
|
||||
pathRewrite: {'^/remove/api' : ''}
|
||||
|
||||
// add base path
|
||||
pathRewrite: {'^/' : '/basepath/'}
|
||||
|
||||
// custom rewriting
|
||||
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
|
||||
|
||||
// custom rewriting, returning Promise
|
||||
pathRewrite: async function (path, req) {
|
||||
const should_add_something = await httpRequestToDecideSomething(path);
|
||||
if (should_add_something) path += "something";
|
||||
return path;
|
||||
}
|
||||
```
|
||||
|
||||
### `router` (object/function)
|
||||
|
||||
Re-target `option.target` for specific requests.
|
||||
|
||||
```javascript
|
||||
// Use `host` and/or `path` to match requests. First match will be used.
|
||||
// The order of the configuration matters.
|
||||
router: {
|
||||
'integration.localhost:3000' : 'http://127.0.0.1:8001', // host only
|
||||
'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
|
||||
'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
|
||||
'/rest' : 'http://127.0.0.1:8004' // path only
|
||||
}
|
||||
|
||||
// Custom router function (string target)
|
||||
router: function(req) {
|
||||
return 'http://127.0.0.1:8004';
|
||||
}
|
||||
|
||||
// Custom router function (target object)
|
||||
router: function(req) {
|
||||
return {
|
||||
protocol: 'https:', // The : is required
|
||||
host: '127.0.0.1',
|
||||
port: 8004
|
||||
};
|
||||
}
|
||||
|
||||
// Asynchronous router function which returns promise
|
||||
router: async function(req) {
|
||||
const url = await doSomeIO();
|
||||
return url;
|
||||
}
|
||||
```
|
||||
|
||||
### `plugins` (Array)
|
||||
|
||||
```js
|
||||
const simpleRequestLogger = (proxyServer, options) => {
|
||||
proxyServer.on('proxyReq', (proxyReq, req, res) => {
|
||||
console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
|
||||
});
|
||||
},
|
||||
|
||||
const config = {
|
||||
target: `http://example.org`,
|
||||
changeOrigin: true,
|
||||
plugins: [simpleRequestLogger],
|
||||
};
|
||||
```
|
||||
|
||||
### `ejectPlugins` (boolean) default: `false`
|
||||
|
||||
If you're not satisfied with the pre-configured plugins, you can eject them by configuring `ejectPlugins: true`.
|
||||
|
||||
NOTE: register your own error handlers to prevent server from crashing.
|
||||
|
||||
```js
|
||||
// eject default plugins and manually add them back
|
||||
|
||||
const {
|
||||
debugProxyErrorsPlugin, // subscribe to proxy errors to prevent server from crashing
|
||||
loggerPlugin, // log proxy events to a logger (ie. console)
|
||||
errorResponsePlugin, // return 5xx response on proxy error
|
||||
proxyEventsPlugin, // implements the "on:" option
|
||||
} = require('http-proxy-middleware');
|
||||
|
||||
createProxyMiddleware({
|
||||
target: `http://example.org`,
|
||||
changeOrigin: true,
|
||||
ejectPlugins: true,
|
||||
plugins: [debugProxyErrorsPlugin, loggerPlugin, errorResponsePlugin, proxyEventsPlugin],
|
||||
});
|
||||
```
|
||||
|
||||
### `logger` (Object)
|
||||
|
||||
Configure a logger to output information from http-proxy-middleware: ie. `console`, `winston`, `pino`, `bunyan`, `log4js`, etc...
|
||||
|
||||
Only `info`, `warn`, `error` are used internally for compatibility across different loggers.
|
||||
|
||||
If you use `winston`, make sure to enable interpolation: <https://github.com/winstonjs/winston#string-interpolation>
|
||||
|
||||
See also logger recipes ([recipes/logger.md](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md)) for more details.
|
||||
|
||||
```javascript
|
||||
createProxyMiddleware({
|
||||
logger: console,
|
||||
});
|
||||
```
|
||||
|
||||
## `http-proxy` events
|
||||
|
||||
Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events) with the `on` option:
|
||||
|
||||
```js
|
||||
createProxyMiddleware({
|
||||
target: 'http://www.example.org',
|
||||
on: {
|
||||
proxyReq: (proxyReq, req, res) => {
|
||||
/* handle proxyReq */
|
||||
},
|
||||
proxyRes: (proxyRes, req, res) => {
|
||||
/* handle proxyRes */
|
||||
},
|
||||
error: (err, req, res) => {
|
||||
/* handle error */
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
- **option.on.error**: function, subscribe to http-proxy's `error` event for custom error handling.
|
||||
|
||||
```javascript
|
||||
function onError(err, req, res, target) {
|
||||
res.writeHead(500, {
|
||||
'Content-Type': 'text/plain',
|
||||
});
|
||||
res.end('Something went wrong. And we are reporting a custom error message.');
|
||||
}
|
||||
```
|
||||
|
||||
- **option.on.proxyRes**: function, subscribe to http-proxy's `proxyRes` event.
|
||||
|
||||
```javascript
|
||||
function onProxyRes(proxyRes, req, res) {
|
||||
proxyRes.headers['x-added'] = 'foobar'; // add new header to response
|
||||
delete proxyRes.headers['x-removed']; // remove header from response
|
||||
}
|
||||
```
|
||||
|
||||
- **option.on.proxyReq**: function, subscribe to http-proxy's `proxyReq` event.
|
||||
|
||||
```javascript
|
||||
function onProxyReq(proxyReq, req, res) {
|
||||
// add custom header to request
|
||||
proxyReq.setHeader('x-added', 'foobar');
|
||||
// or log the req
|
||||
}
|
||||
```
|
||||
|
||||
- **option.on.proxyReqWs**: function, subscribe to http-proxy's `proxyReqWs` event.
|
||||
|
||||
```javascript
|
||||
function onProxyReqWs(proxyReq, req, socket, options, head) {
|
||||
// add custom header
|
||||
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
|
||||
}
|
||||
```
|
||||
|
||||
- **option.on.open**: function, subscribe to http-proxy's `open` event.
|
||||
|
||||
```javascript
|
||||
function onOpen(proxySocket) {
|
||||
// listen for messages coming FROM the target here
|
||||
proxySocket.on('data', hybridParseAndLogMessage);
|
||||
}
|
||||
```
|
||||
|
||||
- **option.on.close**: function, subscribe to http-proxy's `close` event.
|
||||
|
||||
```javascript
|
||||
function onClose(res, socket, head) {
|
||||
// view disconnected websocket connections
|
||||
console.log('Client disconnected');
|
||||
}
|
||||
```
|
||||
|
||||
## `http-proxy` options
|
||||
|
||||
The following options are provided by the underlying [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) library.
|
||||
|
||||
- **option.target**: url string to be parsed with the url module
|
||||
- **option.forward**: url string to be parsed with the url module
|
||||
- **option.agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
|
||||
- **option.ssl**: object to be passed to https.createServer()
|
||||
- **option.ws**: true/false: if you want to proxy websockets
|
||||
- **option.xfwd**: true/false, adds x-forward headers
|
||||
- **option.secure**: true/false, if you want to verify the SSL Certs
|
||||
- **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
|
||||
- **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
|
||||
- **option.ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
|
||||
- **option.localAddress** : Local interface string to bind for outgoing connections
|
||||
- **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
|
||||
- **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
|
||||
- **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
|
||||
- **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
|
||||
- **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
|
||||
- **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
|
||||
- **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
|
||||
|
||||
- `false` (default): disable cookie rewriting
|
||||
- String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
|
||||
- Object: mapping of domains to new domains, use `"*"` to match all domains.
|
||||
For example keep one domain unchanged, rewrite one domain and remove other domains:
|
||||
|
||||
```json
|
||||
cookieDomainRewrite: {
|
||||
"unchanged.domain": "unchanged.domain",
|
||||
"old.domain": "new.domain",
|
||||
"*": ""
|
||||
}
|
||||
```
|
||||
|
||||
- **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
|
||||
|
||||
- `false` (default): disable cookie rewriting
|
||||
- String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
|
||||
- Object: mapping of paths to new paths, use `"*"` to match all paths.
|
||||
For example, to keep one path unchanged, rewrite one path and remove other paths:
|
||||
|
||||
```json
|
||||
cookiePathRewrite: {
|
||||
"/unchanged.path/": "/unchanged.path/",
|
||||
"/old.path/": "/new.path/",
|
||||
"*": ""
|
||||
}
|
||||
```
|
||||
|
||||
- **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
|
||||
- **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
|
||||
- **option.timeout**: timeout (in millis) for incoming requests
|
||||
- **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
|
||||
- **option.selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event
|
||||
- **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const streamify = require('stream-array');
|
||||
const HttpProxy = require('http-proxy');
|
||||
const proxy = new HttpProxy();
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
proxy.web(
|
||||
req,
|
||||
res,
|
||||
{
|
||||
target: 'http://127.0.0.1:4003/',
|
||||
buffer: streamify(req.rawBody),
|
||||
},
|
||||
next,
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## WebSocket
|
||||
|
||||
```javascript
|
||||
// verbose api
|
||||
createProxyMiddleware({ pathFilter: '/', target: 'http://echo.websocket.org', ws: true });
|
||||
```
|
||||
|
||||
### External WebSocket upgrade
|
||||
|
||||
In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the http `upgrade` event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's http `upgrade` event manually.
|
||||
|
||||
```javascript
|
||||
const wsProxy = createProxyMiddleware({ target: 'ws://echo.websocket.org', changeOrigin: true });
|
||||
|
||||
const app = express();
|
||||
app.use(wsProxy);
|
||||
|
||||
const server = app.listen(3000);
|
||||
server.on('upgrade', wsProxy.upgrade); // <-- subscribe to http 'upgrade'
|
||||
```
|
||||
|
||||
## Intercept and manipulate requests
|
||||
|
||||
Intercept requests from downstream by defining `onProxyReq` in `createProxyMiddleware`.
|
||||
|
||||
Currently the only pre-provided request interceptor is `fixRequestBody`, which is used to fix proxied POST requests when `bodyParser` is applied before this middleware.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');
|
||||
|
||||
const proxy = createProxyMiddleware({
|
||||
/**
|
||||
* Fix bodyParser
|
||||
**/
|
||||
on: {
|
||||
proxyReq: fixRequestBody,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Intercept and manipulate responses
|
||||
|
||||
Intercept responses from upstream with `responseInterceptor`. (Make sure to set `selfHandleResponse: true`)
|
||||
|
||||
Responses which are compressed with `brotli`, `gzip` and `deflate` will be decompressed automatically. The response will be returned as `buffer` ([docs](https://nodejs.org/api/buffer.html)) which you can manipulate.
|
||||
|
||||
With `buffer`, response manipulation is not limited to text responses (html/css/js, etc...); image manipulation will be possible too. ([example](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md#manipulate-image-response))
|
||||
|
||||
NOTE: `responseInterceptor` disables streaming of target's response.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
|
||||
|
||||
const proxy = createProxyMiddleware({
|
||||
/**
|
||||
* IMPORTANT: avoid res.end being called automatically
|
||||
**/
|
||||
selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()
|
||||
|
||||
/**
|
||||
* Intercept response and replace 'Hello' with 'Goodbye'
|
||||
**/
|
||||
on: {
|
||||
proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
|
||||
const response = responseBuffer.toString('utf8'); // convert buffer to string
|
||||
return response.replace('Hello', 'Goodbye'); // manipulate response and return the result
|
||||
}),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Check out [interception recipes](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md#readme) for more examples.
|
||||
|
||||
## Node.js 17+: ECONNREFUSED issue with IPv6 and localhost ([#705](https://github.com/chimurai/http-proxy-middleware/issues/705))
|
||||
|
||||
Node.js 17+ no longer prefers IPv4 over IPv6 for DNS lookups.
|
||||
E.g. It's **not** guaranteed that `localhost` will be resolved to `127.0.0.1` – it might just as well be `::1` (or some other IP address).
|
||||
|
||||
If your target server only accepts IPv4 connections, trying to proxy to `localhost` will fail if resolved to `::1` (IPv6).
|
||||
|
||||
Ways to solve it:
|
||||
|
||||
- Change `target: "http://localhost"` to `target: "http://127.0.0.1"` (IPv4).
|
||||
- Change the target server to (also) accept IPv6 connections.
|
||||
- Add this flag when running `node`: `node index.js --dns-result-order=ipv4first`. (Not recommended.)
|
||||
|
||||
> Note: There’s a thing called [Happy Eyeballs](https://en.wikipedia.org/wiki/Happy_Eyeballs) which means connecting to both IPv4 and IPv6 in parallel, which Node.js doesn’t have, but explains why for example `curl` can connect.
|
||||
|
||||
## Debugging
|
||||
|
||||
Configure the `DEBUG` environment variable enable debug logging.
|
||||
|
||||
See [`debug`](https://github.com/debug-js/debug#readme) project for more options.
|
||||
|
||||
```shell
|
||||
DEBUG=http-proxy-middleware* node server.js
|
||||
|
||||
$ http-proxy-middleware proxy created +0ms
|
||||
$ http-proxy-middleware proxying request to target: 'http://www.example.org' +359ms
|
||||
```
|
||||
|
||||
## Working examples
|
||||
|
||||
View and play around with [working examples](https://github.com/chimurai/http-proxy-middleware/tree/master/examples).
|
||||
|
||||
- Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
|
||||
- express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
|
||||
- connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
|
||||
- WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))
|
||||
- Response Manipulation ([example source](https://github.com/chimurai/http-proxy-middleware/blob/master/examples/response-interceptor/index.js))
|
||||
|
||||
## Recipes
|
||||
|
||||
View the [recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes) for common use cases.
|
||||
|
||||
## Compatible servers
|
||||
|
||||
`http-proxy-middleware` is compatible with the following servers:
|
||||
|
||||
- [connect](https://www.npmjs.com/package/connect)
|
||||
- [express](https://www.npmjs.com/package/express)
|
||||
- [next.js](https://www.npmjs.com/package/next)
|
||||
- [fastify](https://www.npmjs.com/package/fastify)
|
||||
- [browser-sync](https://www.npmjs.com/package/browser-sync)
|
||||
- [lite-server](https://www.npmjs.com/package/lite-server)
|
||||
- [polka](https://github.com/lukeed/polka)
|
||||
- [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
|
||||
- [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
|
||||
- [gulp-connect](https://www.npmjs.com/package/gulp-connect)
|
||||
- [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
|
||||
|
||||
Sample implementations can be found in the [server recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes/servers.md).
|
||||
|
||||
## Tests
|
||||
|
||||
Run the test suite:
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
$ yarn
|
||||
|
||||
# linting
|
||||
$ yarn lint
|
||||
$ yarn lint:fix
|
||||
|
||||
# building (compile typescript to js)
|
||||
$ yarn build
|
||||
|
||||
# unit tests
|
||||
$ yarn test
|
||||
|
||||
# code coverage
|
||||
$ yarn cover
|
||||
|
||||
# check spelling mistakes
|
||||
$ yarn spellcheck
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
- [View changelog](https://github.com/chimurai/http-proxy-middleware/blob/master/CHANGELOG.md)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2024 Steven Chim
|
||||
2
node_modules/http-proxy-middleware/dist/configuration.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/configuration.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Options } from './types';
|
||||
export declare function verifyConfig<TReq, TRes>(options: Options<TReq, TRes>): void;
|
||||
9
node_modules/http-proxy-middleware/dist/configuration.js
generated
vendored
Normal file
9
node_modules/http-proxy-middleware/dist/configuration.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.verifyConfig = verifyConfig;
|
||||
const errors_1 = require("./errors");
|
||||
function verifyConfig(options) {
|
||||
if (!options.target && !options.router) {
|
||||
throw new Error(errors_1.ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING);
|
||||
}
|
||||
}
|
||||
5
node_modules/http-proxy-middleware/dist/debug.d.ts
generated
vendored
Normal file
5
node_modules/http-proxy-middleware/dist/debug.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import * as createDebug from 'debug';
|
||||
/**
|
||||
* Debug instance with the given namespace: http-proxy-middleware
|
||||
*/
|
||||
export declare const Debug: createDebug.Debugger;
|
||||
8
node_modules/http-proxy-middleware/dist/debug.js
generated
vendored
Normal file
8
node_modules/http-proxy-middleware/dist/debug.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Debug = void 0;
|
||||
const createDebug = require("debug");
|
||||
/**
|
||||
* Debug instance with the given namespace: http-proxy-middleware
|
||||
*/
|
||||
exports.Debug = createDebug('http-proxy-middleware');
|
||||
6
node_modules/http-proxy-middleware/dist/errors.d.ts
generated
vendored
Normal file
6
node_modules/http-proxy-middleware/dist/errors.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export declare enum ERRORS {
|
||||
ERR_CONFIG_FACTORY_TARGET_MISSING = "[HPM] Missing \"target\" option. Example: {target: \"http://www.example.org\"}",
|
||||
ERR_CONTEXT_MATCHER_GENERIC = "[HPM] Invalid pathFilter. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]",
|
||||
ERR_CONTEXT_MATCHER_INVALID_ARRAY = "[HPM] Invalid pathFilter. Plain paths (e.g. \"/api\") can not be mixed with globs (e.g. \"/api/**\"). Expecting something like: [\"/api\", \"/ajax\"] or [\"/api/**\", \"!**.html\"].",
|
||||
ERR_PATH_REWRITER_CONFIG = "[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function"
|
||||
}
|
||||
10
node_modules/http-proxy-middleware/dist/errors.js
generated
vendored
Normal file
10
node_modules/http-proxy-middleware/dist/errors.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ERRORS = void 0;
|
||||
var ERRORS;
|
||||
(function (ERRORS) {
|
||||
ERRORS["ERR_CONFIG_FACTORY_TARGET_MISSING"] = "[HPM] Missing \"target\" option. Example: {target: \"http://www.example.org\"}";
|
||||
ERRORS["ERR_CONTEXT_MATCHER_GENERIC"] = "[HPM] Invalid pathFilter. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]";
|
||||
ERRORS["ERR_CONTEXT_MATCHER_INVALID_ARRAY"] = "[HPM] Invalid pathFilter. Plain paths (e.g. \"/api\") can not be mixed with globs (e.g. \"/api/**\"). Expecting something like: [\"/api\", \"/ajax\"] or [\"/api/**\", \"!**.html\"].";
|
||||
ERRORS["ERR_PATH_REWRITER_CONFIG"] = "[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function";
|
||||
})(ERRORS || (exports.ERRORS = ERRORS = {}));
|
||||
3
node_modules/http-proxy-middleware/dist/factory.d.ts
generated
vendored
Normal file
3
node_modules/http-proxy-middleware/dist/factory.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { Options, RequestHandler, NextFunction } from './types';
|
||||
import type * as http from 'http';
|
||||
export declare function createProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction>(options: Options<TReq, TRes>): RequestHandler<TReq, TRes, TNext>;
|
||||
8
node_modules/http-proxy-middleware/dist/factory.js
generated
vendored
Normal file
8
node_modules/http-proxy-middleware/dist/factory.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createProxyMiddleware = createProxyMiddleware;
|
||||
const http_proxy_middleware_1 = require("./http-proxy-middleware");
|
||||
function createProxyMiddleware(options) {
|
||||
const { middleware } = new http_proxy_middleware_1.HttpProxyMiddleware(options);
|
||||
return middleware;
|
||||
}
|
||||
2
node_modules/http-proxy-middleware/dist/get-plugins.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/get-plugins.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { Options, Plugin } from './types';
|
||||
export declare function getPlugins<TReq, TRes>(options: Options<TReq, TRes>): Plugin<TReq, TRes>[];
|
||||
13
node_modules/http-proxy-middleware/dist/get-plugins.js
generated
vendored
Normal file
13
node_modules/http-proxy-middleware/dist/get-plugins.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPlugins = getPlugins;
|
||||
const default_1 = require("./plugins/default");
|
||||
function getPlugins(options) {
|
||||
// don't load default errorResponsePlugin if user has specified their own
|
||||
const maybeErrorResponsePlugin = options.on?.error ? [] : [default_1.errorResponsePlugin];
|
||||
const defaultPlugins = options.ejectPlugins
|
||||
? [] // no default plugins when ejecting
|
||||
: [default_1.debugProxyErrorsPlugin, default_1.proxyEventsPlugin, default_1.loggerPlugin, ...maybeErrorResponsePlugin];
|
||||
const userPlugins = options.plugins ?? [];
|
||||
return [...defaultPlugins, ...userPlugins];
|
||||
}
|
||||
8
node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts
generated
vendored
Normal file
8
node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type * as http from 'http';
|
||||
export type BodyParserLikeRequest = http.IncomingMessage & {
|
||||
body: any;
|
||||
};
|
||||
/**
|
||||
* Fix proxied body if bodyParser is involved.
|
||||
*/
|
||||
export declare function fixRequestBody<TReq = http.IncomingMessage>(proxyReq: http.ClientRequest, req: TReq): void;
|
||||
25
node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js
generated
vendored
Normal file
25
node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fixRequestBody = fixRequestBody;
|
||||
const querystring = require("querystring");
|
||||
/**
|
||||
* Fix proxied body if bodyParser is involved.
|
||||
*/
|
||||
function fixRequestBody(proxyReq, req) {
|
||||
const requestBody = req.body;
|
||||
if (!requestBody) {
|
||||
return;
|
||||
}
|
||||
const contentType = proxyReq.getHeader('Content-Type');
|
||||
const writeBody = (bodyData) => {
|
||||
// deepcode ignore ContentLengthInCode: bodyParser fix
|
||||
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
|
||||
proxyReq.write(bodyData);
|
||||
};
|
||||
if (contentType && (contentType.includes('application/json') || contentType.includes('+json'))) {
|
||||
writeBody(JSON.stringify(requestBody));
|
||||
}
|
||||
if (contentType && contentType.includes('application/x-www-form-urlencoded')) {
|
||||
writeBody(querystring.stringify(requestBody));
|
||||
}
|
||||
}
|
||||
1
node_modules/http-proxy-middleware/dist/handlers/index.d.ts
generated
vendored
Normal file
1
node_modules/http-proxy-middleware/dist/handlers/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './public';
|
||||
17
node_modules/http-proxy-middleware/dist/handlers/index.js
generated
vendored
Normal file
17
node_modules/http-proxy-middleware/dist/handlers/index.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./public"), exports);
|
||||
2
node_modules/http-proxy-middleware/dist/handlers/public.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/handlers/public.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export { responseInterceptor } from './response-interceptor';
|
||||
export { fixRequestBody } from './fix-request-body';
|
||||
7
node_modules/http-proxy-middleware/dist/handlers/public.js
generated
vendored
Normal file
7
node_modules/http-proxy-middleware/dist/handlers/public.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fixRequestBody = exports.responseInterceptor = void 0;
|
||||
var response_interceptor_1 = require("./response-interceptor");
|
||||
Object.defineProperty(exports, "responseInterceptor", { enumerable: true, get: function () { return response_interceptor_1.responseInterceptor; } });
|
||||
var fix_request_body_1 = require("./fix-request-body");
|
||||
Object.defineProperty(exports, "fixRequestBody", { enumerable: true, get: function () { return fix_request_body_1.fixRequestBody; } });
|
||||
11
node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts
generated
vendored
Normal file
11
node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type * as http from 'http';
|
||||
type Interceptor<TReq = http.IncomingMessage, TRes = http.ServerResponse> = (buffer: Buffer, proxyRes: TReq, req: TReq, res: TRes) => Promise<Buffer | string>;
|
||||
/**
|
||||
* Intercept responses from upstream.
|
||||
* Automatically decompress (deflate, gzip, brotli).
|
||||
* Give developer the opportunity to modify intercepted Buffer and http.ServerResponse
|
||||
*
|
||||
* NOTE: must set options.selfHandleResponse=true (prevent automatic call of res.end())
|
||||
*/
|
||||
export declare function responseInterceptor<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(interceptor: Interceptor<TReq, TRes>): (proxyRes: TReq, req: TReq, res: TRes) => Promise<void>;
|
||||
export {};
|
||||
94
node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js
generated
vendored
Normal file
94
node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.responseInterceptor = responseInterceptor;
|
||||
const zlib = require("zlib");
|
||||
const debug_1 = require("../debug");
|
||||
const function_1 = require("../utils/function");
|
||||
const debug = debug_1.Debug.extend('response-interceptor');
|
||||
/**
|
||||
* Intercept responses from upstream.
|
||||
* Automatically decompress (deflate, gzip, brotli).
|
||||
* Give developer the opportunity to modify intercepted Buffer and http.ServerResponse
|
||||
*
|
||||
* NOTE: must set options.selfHandleResponse=true (prevent automatic call of res.end())
|
||||
*/
|
||||
function responseInterceptor(interceptor) {
|
||||
return async function proxyResResponseInterceptor(proxyRes, req, res) {
|
||||
debug('intercept proxy response');
|
||||
const originalProxyRes = proxyRes;
|
||||
let buffer = Buffer.from('', 'utf8');
|
||||
// decompress proxy response
|
||||
const _proxyRes = decompress(proxyRes, proxyRes.headers['content-encoding']);
|
||||
// concat data stream
|
||||
_proxyRes.on('data', (chunk) => (buffer = Buffer.concat([buffer, chunk])));
|
||||
_proxyRes.on('end', async () => {
|
||||
// copy original headers
|
||||
copyHeaders(proxyRes, res);
|
||||
// call interceptor with intercepted response (buffer)
|
||||
debug('call interceptor function: %s', (0, function_1.getFunctionName)(interceptor));
|
||||
const interceptedBuffer = Buffer.from(await interceptor(buffer, originalProxyRes, req, res));
|
||||
// set correct content-length (with double byte character support)
|
||||
debug('set content-length: %s', Buffer.byteLength(interceptedBuffer, 'utf8'));
|
||||
res.setHeader('content-length', Buffer.byteLength(interceptedBuffer, 'utf8'));
|
||||
debug('write intercepted response');
|
||||
res.write(interceptedBuffer);
|
||||
res.end();
|
||||
});
|
||||
_proxyRes.on('error', (error) => {
|
||||
res.end(`Error fetching proxied request: ${error.message}`);
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Streaming decompression of proxy response
|
||||
* source: https://github.com/apache/superset/blob/9773aba522e957ed9423045ca153219638a85d2f/superset-frontend/webpack.proxy-config.js#L116
|
||||
*/
|
||||
function decompress(proxyRes, contentEncoding) {
|
||||
let _proxyRes = proxyRes;
|
||||
let decompress;
|
||||
switch (contentEncoding) {
|
||||
case 'gzip':
|
||||
decompress = zlib.createGunzip();
|
||||
break;
|
||||
case 'br':
|
||||
decompress = zlib.createBrotliDecompress();
|
||||
break;
|
||||
case 'deflate':
|
||||
decompress = zlib.createInflate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (decompress) {
|
||||
debug(`decompress proxy response with 'content-encoding': %s`, contentEncoding);
|
||||
_proxyRes.pipe(decompress);
|
||||
_proxyRes = decompress;
|
||||
}
|
||||
return _proxyRes;
|
||||
}
|
||||
/**
|
||||
* Copy original headers
|
||||
* https://github.com/apache/superset/blob/9773aba522e957ed9423045ca153219638a85d2f/superset-frontend/webpack.proxy-config.js#L78
|
||||
*/
|
||||
function copyHeaders(originalResponse, response) {
|
||||
debug('copy original response headers');
|
||||
response.statusCode = originalResponse.statusCode;
|
||||
response.statusMessage = originalResponse.statusMessage;
|
||||
if (response.setHeader) {
|
||||
let keys = Object.keys(originalResponse.headers);
|
||||
// ignore chunked, brotli, gzip, deflate headers
|
||||
keys = keys.filter((key) => !['content-encoding', 'transfer-encoding'].includes(key));
|
||||
keys.forEach((key) => {
|
||||
let value = originalResponse.headers[key];
|
||||
if (key === 'set-cookie') {
|
||||
// remove cookie domain
|
||||
value = Array.isArray(value) ? value : [value];
|
||||
value = value.map((x) => x.replace(/Domain=[^;]+?/i, ''));
|
||||
}
|
||||
response.setHeader(key, value);
|
||||
});
|
||||
}
|
||||
else {
|
||||
response.headers = originalResponse.headers;
|
||||
}
|
||||
}
|
||||
29
node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts
generated
vendored
Normal file
29
node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { RequestHandler, Options } from './types';
|
||||
export declare class HttpProxyMiddleware<TReq, TRes> {
|
||||
private wsInternalSubscribed;
|
||||
private serverOnCloseSubscribed;
|
||||
private proxyOptions;
|
||||
private proxy;
|
||||
private pathRewriter;
|
||||
private logger;
|
||||
constructor(options: Options<TReq, TRes>);
|
||||
middleware: RequestHandler;
|
||||
private registerPlugins;
|
||||
private catchUpgradeRequest;
|
||||
private handleUpgrade;
|
||||
/**
|
||||
* Determine whether request should be proxied.
|
||||
*/
|
||||
private shouldProxy;
|
||||
/**
|
||||
* Apply option.router and option.pathRewrite
|
||||
* Order matters:
|
||||
* Router uses original path for routing;
|
||||
* NOT the modified path, after it has been rewritten by pathRewrite
|
||||
* @param {Object} req
|
||||
* @return {Object} proxy options
|
||||
*/
|
||||
private prepareProxyRequest;
|
||||
private applyRouter;
|
||||
private applyPathRewrite;
|
||||
}
|
||||
154
node_modules/http-proxy-middleware/dist/http-proxy-middleware.js
generated
vendored
Normal file
154
node_modules/http-proxy-middleware/dist/http-proxy-middleware.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HttpProxyMiddleware = void 0;
|
||||
const httpProxy = require("http-proxy");
|
||||
const configuration_1 = require("./configuration");
|
||||
const get_plugins_1 = require("./get-plugins");
|
||||
const path_filter_1 = require("./path-filter");
|
||||
const PathRewriter = require("./path-rewriter");
|
||||
const Router = require("./router");
|
||||
const debug_1 = require("./debug");
|
||||
const function_1 = require("./utils/function");
|
||||
const logger_1 = require("./logger");
|
||||
class HttpProxyMiddleware {
|
||||
constructor(options) {
|
||||
this.wsInternalSubscribed = false;
|
||||
this.serverOnCloseSubscribed = false;
|
||||
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
|
||||
this.middleware = (async (req, res, next) => {
|
||||
if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
|
||||
try {
|
||||
const activeProxyOptions = await this.prepareProxyRequest(req);
|
||||
(0, debug_1.Debug)(`proxy request to target: %O`, activeProxyOptions.target);
|
||||
this.proxy.web(req, res, activeProxyOptions);
|
||||
}
|
||||
catch (err) {
|
||||
next?.(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
next?.();
|
||||
}
|
||||
/**
|
||||
* Get the server object to subscribe to server events;
|
||||
* 'upgrade' for websocket and 'close' for graceful shutdown
|
||||
*
|
||||
* NOTE:
|
||||
* req.socket: node >= 13
|
||||
* req.connection: node < 13 (Remove this when node 12/13 support is dropped)
|
||||
*/
|
||||
const server = (req.socket ?? req.connection)?.server;
|
||||
if (server && !this.serverOnCloseSubscribed) {
|
||||
server.on('close', () => {
|
||||
(0, debug_1.Debug)('server close signal received: closing proxy server');
|
||||
this.proxy.close();
|
||||
});
|
||||
this.serverOnCloseSubscribed = true;
|
||||
}
|
||||
if (this.proxyOptions.ws === true) {
|
||||
// use initial request to access the server object to subscribe to http upgrade event
|
||||
this.catchUpgradeRequest(server);
|
||||
}
|
||||
});
|
||||
this.catchUpgradeRequest = (server) => {
|
||||
if (!this.wsInternalSubscribed) {
|
||||
(0, debug_1.Debug)('subscribing to server upgrade event');
|
||||
server.on('upgrade', this.handleUpgrade);
|
||||
// prevent duplicate upgrade handling;
|
||||
// in case external upgrade is also configured
|
||||
this.wsInternalSubscribed = true;
|
||||
}
|
||||
};
|
||||
this.handleUpgrade = async (req, socket, head) => {
|
||||
if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
|
||||
const activeProxyOptions = await this.prepareProxyRequest(req);
|
||||
this.proxy.ws(req, socket, head, activeProxyOptions);
|
||||
(0, debug_1.Debug)('server upgrade event received. Proxying WebSocket');
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Determine whether request should be proxied.
|
||||
*/
|
||||
this.shouldProxy = (pathFilter, req) => {
|
||||
try {
|
||||
return (0, path_filter_1.matchPathFilter)(pathFilter, req.url, req);
|
||||
}
|
||||
catch (err) {
|
||||
(0, debug_1.Debug)('Error: matchPathFilter() called with request url: ', `"${req.url}"`);
|
||||
this.logger.error(err);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Apply option.router and option.pathRewrite
|
||||
* Order matters:
|
||||
* Router uses original path for routing;
|
||||
* NOT the modified path, after it has been rewritten by pathRewrite
|
||||
* @param {Object} req
|
||||
* @return {Object} proxy options
|
||||
*/
|
||||
this.prepareProxyRequest = async (req) => {
|
||||
/**
|
||||
* Incorrect usage confirmed: https://github.com/expressjs/express/issues/4854#issuecomment-1066171160
|
||||
* Temporary restore req.url patch for {@link src/legacy/create-proxy-middleware.ts legacyCreateProxyMiddleware()}
|
||||
* FIXME: remove this patch in future release
|
||||
*/
|
||||
if (this.middleware.__LEGACY_HTTP_PROXY_MIDDLEWARE__) {
|
||||
req.url = req.originalUrl || req.url;
|
||||
}
|
||||
const newProxyOptions = Object.assign({}, this.proxyOptions);
|
||||
// Apply in order:
|
||||
// 1. option.router
|
||||
// 2. option.pathRewrite
|
||||
await this.applyRouter(req, newProxyOptions);
|
||||
await this.applyPathRewrite(req, this.pathRewriter);
|
||||
return newProxyOptions;
|
||||
};
|
||||
// Modify option.target when router present.
|
||||
this.applyRouter = async (req, options) => {
|
||||
let newTarget;
|
||||
if (options.router) {
|
||||
newTarget = await Router.getTarget(req, options);
|
||||
if (newTarget) {
|
||||
(0, debug_1.Debug)('router new target: "%s"', newTarget);
|
||||
options.target = newTarget;
|
||||
}
|
||||
}
|
||||
};
|
||||
// rewrite path
|
||||
this.applyPathRewrite = async (req, pathRewriter) => {
|
||||
if (pathRewriter) {
|
||||
const path = await pathRewriter(req.url, req);
|
||||
if (typeof path === 'string') {
|
||||
(0, debug_1.Debug)('pathRewrite new path: %s', req.url);
|
||||
req.url = path;
|
||||
}
|
||||
else {
|
||||
(0, debug_1.Debug)('pathRewrite: no rewritten path found: %s', req.url);
|
||||
}
|
||||
}
|
||||
};
|
||||
(0, configuration_1.verifyConfig)(options);
|
||||
this.proxyOptions = options;
|
||||
this.logger = (0, logger_1.getLogger)(options);
|
||||
(0, debug_1.Debug)(`create proxy server`);
|
||||
this.proxy = httpProxy.createProxyServer({});
|
||||
this.registerPlugins(this.proxy, this.proxyOptions);
|
||||
this.pathRewriter = PathRewriter.createPathRewriter(this.proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
|
||||
// https://github.com/chimurai/http-proxy-middleware/issues/19
|
||||
// expose function to upgrade externally
|
||||
this.middleware.upgrade = (req, socket, head) => {
|
||||
if (!this.wsInternalSubscribed) {
|
||||
this.handleUpgrade(req, socket, head);
|
||||
}
|
||||
};
|
||||
}
|
||||
registerPlugins(proxy, options) {
|
||||
const plugins = (0, get_plugins_1.getPlugins)(options);
|
||||
plugins.forEach((plugin) => {
|
||||
(0, debug_1.Debug)(`register plugin: "${(0, function_1.getFunctionName)(plugin)}"`);
|
||||
plugin(proxy, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.HttpProxyMiddleware = HttpProxyMiddleware;
|
||||
11
node_modules/http-proxy-middleware/dist/index.d.ts
generated
vendored
Normal file
11
node_modules/http-proxy-middleware/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from './factory';
|
||||
export * from './handlers';
|
||||
export type { Filter, Options, RequestHandler } from './types';
|
||||
/**
|
||||
* Default plugins
|
||||
*/
|
||||
export * from './plugins/default';
|
||||
/**
|
||||
* Legacy exports
|
||||
*/
|
||||
export * from './legacy';
|
||||
26
node_modules/http-proxy-middleware/dist/index.js
generated
vendored
Normal file
26
node_modules/http-proxy-middleware/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./factory"), exports);
|
||||
__exportStar(require("./handlers"), exports);
|
||||
/**
|
||||
* Default plugins
|
||||
*/
|
||||
__exportStar(require("./plugins/default"), exports);
|
||||
/**
|
||||
* Legacy exports
|
||||
*/
|
||||
__exportStar(require("./legacy"), exports);
|
||||
12
node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.d.ts
generated
vendored
Normal file
12
node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Filter, RequestHandler } from '../types';
|
||||
import { LegacyOptions } from './types';
|
||||
import type * as http from 'http';
|
||||
/**
|
||||
* @deprecated
|
||||
* This function is deprecated and will be removed in a future version.
|
||||
*
|
||||
* Use {@link createProxyMiddleware} instead.
|
||||
*/
|
||||
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(shortHand: string): RequestHandler<TReq, TRes>;
|
||||
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;
|
||||
export declare function legacyCreateProxyMiddleware<TReq = http.IncomingMessage, TRes = http.ServerResponse>(legacyContext: Filter<TReq>, legacyOptions: LegacyOptions<TReq, TRes>): RequestHandler<TReq, TRes>;
|
||||
16
node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.js
generated
vendored
Normal file
16
node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.legacyCreateProxyMiddleware = legacyCreateProxyMiddleware;
|
||||
const factory_1 = require("../factory");
|
||||
const debug_1 = require("../debug");
|
||||
const options_adapter_1 = require("./options-adapter");
|
||||
const debug = debug_1.Debug.extend('legacy-create-proxy-middleware');
|
||||
function legacyCreateProxyMiddleware(legacyContext, legacyOptions) {
|
||||
debug('init');
|
||||
const options = (0, options_adapter_1.legacyOptionsAdapter)(legacyContext, legacyOptions);
|
||||
const proxyMiddleware = (0, factory_1.createProxyMiddleware)(options);
|
||||
// https://github.com/chimurai/http-proxy-middleware/pull/731/files#diff-07e6ad10bda0df091b737caed42767657cd0bd74a01246a1a0b7ab59c0f6e977L118
|
||||
debug('add marker for patching req.url (old behavior)');
|
||||
proxyMiddleware.__LEGACY_HTTP_PROXY_MIDDLEWARE__ = true;
|
||||
return proxyMiddleware;
|
||||
}
|
||||
1
node_modules/http-proxy-middleware/dist/legacy/index.d.ts
generated
vendored
Normal file
1
node_modules/http-proxy-middleware/dist/legacy/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './public';
|
||||
17
node_modules/http-proxy-middleware/dist/legacy/index.js
generated
vendored
Normal file
17
node_modules/http-proxy-middleware/dist/legacy/index.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./public"), exports);
|
||||
6
node_modules/http-proxy-middleware/dist/legacy/options-adapter.d.ts
generated
vendored
Normal file
6
node_modules/http-proxy-middleware/dist/legacy/options-adapter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Filter, Options } from '../types';
|
||||
import { LegacyOptions } from './types';
|
||||
/**
|
||||
* Convert {@link LegacyOptions legacy Options} to new {@link Options}
|
||||
*/
|
||||
export declare function legacyOptionsAdapter<TReq, TRes>(legacyContext: Filter<TReq> | LegacyOptions<TReq, TRes>, legacyOptions: LegacyOptions<TReq, TRes>): Options<TReq, TRes>;
|
||||
97
node_modules/http-proxy-middleware/dist/legacy/options-adapter.js
generated
vendored
Normal file
97
node_modules/http-proxy-middleware/dist/legacy/options-adapter.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.legacyOptionsAdapter = legacyOptionsAdapter;
|
||||
const url = require("url");
|
||||
const debug_1 = require("../debug");
|
||||
const logger_1 = require("../logger");
|
||||
const debug = debug_1.Debug.extend('legacy-options-adapter');
|
||||
// https://github.com/chimurai/http-proxy-middleware/blob/7341704d0aa9d1606dfd37ebfdffddd34c894784/src/_handlers.ts#L20-L27
|
||||
const proxyEventMap = {
|
||||
onError: 'error',
|
||||
onProxyReq: 'proxyReq',
|
||||
onProxyRes: 'proxyRes',
|
||||
onProxyReqWs: 'proxyReqWs',
|
||||
onOpen: 'open',
|
||||
onClose: 'close',
|
||||
};
|
||||
/**
|
||||
* Convert {@link LegacyOptions legacy Options} to new {@link Options}
|
||||
*/
|
||||
function legacyOptionsAdapter(legacyContext, legacyOptions) {
|
||||
let options = {};
|
||||
let logger;
|
||||
// https://github.com/chimurai/http-proxy-middleware/pull/716
|
||||
if (typeof legacyContext === 'string' && !!url.parse(legacyContext).host) {
|
||||
throw new Error(`Shorthand syntax is removed from legacyCreateProxyMiddleware().
|
||||
Please use "legacyCreateProxyMiddleware({ target: 'http://www.example.org' })" instead.
|
||||
|
||||
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-shorthand-usage
|
||||
`);
|
||||
}
|
||||
// detect old "context" argument and convert to "options.pathFilter"
|
||||
// https://github.com/chimurai/http-proxy-middleware/pull/722/files#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80L4
|
||||
if (legacyContext && legacyOptions) {
|
||||
debug('map legacy context/filter to options.pathFilter');
|
||||
options = { ...legacyOptions, pathFilter: legacyContext };
|
||||
logger = getLegacyLogger(options);
|
||||
logger.warn(`[http-proxy-middleware] Legacy "context" argument is deprecated. Migrate your "context" to "options.pathFilter":
|
||||
|
||||
const options = {
|
||||
pathFilter: '${legacyContext}',
|
||||
}
|
||||
|
||||
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-context-argument
|
||||
`);
|
||||
}
|
||||
else if (legacyContext && !legacyOptions) {
|
||||
options = { ...legacyContext };
|
||||
logger = getLegacyLogger(options);
|
||||
}
|
||||
else {
|
||||
logger = getLegacyLogger({});
|
||||
}
|
||||
// map old event names to new event names
|
||||
// https://github.com/chimurai/http-proxy-middleware/pull/745/files#diff-c54113cf61ec99691748a3890bfbeb00e10efb3f0a76f03a0fd9ec49072e410aL48-L53
|
||||
Object.entries(proxyEventMap).forEach(([legacyEventName, proxyEventName]) => {
|
||||
if (options[legacyEventName]) {
|
||||
options.on = { ...options.on };
|
||||
options.on[proxyEventName] = options[legacyEventName];
|
||||
debug('map legacy event "%s" to "on.%s"', legacyEventName, proxyEventName);
|
||||
logger.warn(`[http-proxy-middleware] Legacy "${legacyEventName}" is deprecated. Migrate to "options.on.${proxyEventName}":
|
||||
|
||||
const options = {
|
||||
on: {
|
||||
${proxyEventName}: () => {},
|
||||
},
|
||||
}
|
||||
|
||||
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#refactored-proxy-events
|
||||
`);
|
||||
}
|
||||
});
|
||||
// map old logProvider to new logger
|
||||
// https://github.com/chimurai/http-proxy-middleware/pull/749
|
||||
const logProvider = options.logProvider && options.logProvider();
|
||||
const logLevel = options.logLevel;
|
||||
debug('legacy logLevel', logLevel);
|
||||
debug('legacy logProvider: %O', logProvider);
|
||||
if (typeof logLevel === 'string' && logLevel !== 'silent') {
|
||||
debug('map "logProvider" to "logger"');
|
||||
logger.warn(`[http-proxy-middleware] Legacy "logLevel" and "logProvider" are deprecated. Migrate to "options.logger":
|
||||
|
||||
const options = {
|
||||
logger: console,
|
||||
}
|
||||
|
||||
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-logprovider-and-loglevel-options
|
||||
`);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
function getLegacyLogger(options) {
|
||||
const legacyLogger = options.logProvider && options.logProvider();
|
||||
if (legacyLogger) {
|
||||
options.logger = legacyLogger;
|
||||
}
|
||||
return (0, logger_1.getLogger)(options);
|
||||
}
|
||||
2
node_modules/http-proxy-middleware/dist/legacy/public.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/legacy/public.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export { legacyCreateProxyMiddleware } from './create-proxy-middleware';
|
||||
export { LegacyOptions } from './types';
|
||||
5
node_modules/http-proxy-middleware/dist/legacy/public.js
generated
vendored
Normal file
5
node_modules/http-proxy-middleware/dist/legacy/public.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.legacyCreateProxyMiddleware = void 0;
|
||||
var create_proxy_middleware_1 = require("./create-proxy-middleware");
|
||||
Object.defineProperty(exports, "legacyCreateProxyMiddleware", { enumerable: true, get: function () { return create_proxy_middleware_1.legacyCreateProxyMiddleware; } });
|
||||
111
node_modules/http-proxy-middleware/dist/legacy/types.d.ts
generated
vendored
Normal file
111
node_modules/http-proxy-middleware/dist/legacy/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
import type * as http from 'http';
|
||||
import { Options } from '../types';
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Will be removed in a future version.
|
||||
*/
|
||||
export interface LegacyOptions<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends Options<TReq, TRes> {
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.error` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* error: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onError?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.proxyRes` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* proxyRes: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onProxyRes?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.proxyReq` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* proxyReq: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onProxyReq?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.proxyReqWs` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* proxyReqWs: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onProxyReqWs?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.open` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* open: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onOpen?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `on.close` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* on: {
|
||||
* close: () => {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onClose?: (...args: any[]) => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `logger` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* logger: console
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
logProvider?: any;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `logger` instead.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* logger: console
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
logLevel?: any;
|
||||
}
|
||||
2
node_modules/http-proxy-middleware/dist/legacy/types.js
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/legacy/types.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
2
node_modules/http-proxy-middleware/dist/logger.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/logger.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Logger, Options } from './types';
|
||||
export declare function getLogger(options: Options): Logger;
|
||||
24
node_modules/http-proxy-middleware/dist/logger.js
generated
vendored
Normal file
24
node_modules/http-proxy-middleware/dist/logger.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getLogger = getLogger;
|
||||
/**
|
||||
* Compatibility matrix
|
||||
*
|
||||
| Library | log | info | warn | error | \<interpolation\> |
|
||||
|----------|:------|:-------|:------|:--------|:------------------|
|
||||
| console | ✅ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
|
||||
| bunyan | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
|
||||
| pino | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
|
||||
| winston | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O)^1 |
|
||||
| log4js | ❌ | ✅ | ✅ | ✅ | ✅ (%s %o %O) |
|
||||
*
|
||||
* ^1: https://github.com/winstonjs/winston#string-interpolation
|
||||
*/
|
||||
const noopLogger = {
|
||||
info: () => { },
|
||||
warn: () => { },
|
||||
error: () => { },
|
||||
};
|
||||
function getLogger(options) {
|
||||
return options.logger || noopLogger;
|
||||
}
|
||||
3
node_modules/http-proxy-middleware/dist/path-filter.d.ts
generated
vendored
Normal file
3
node_modules/http-proxy-middleware/dist/path-filter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { Filter } from './types';
|
||||
import type * as http from 'http';
|
||||
export declare function matchPathFilter<TReq = http.IncomingMessage>(pathFilter: Filter<TReq> | undefined, uri: string | undefined, req: http.IncomingMessage): boolean;
|
||||
80
node_modules/http-proxy-middleware/dist/path-filter.js
generated
vendored
Normal file
80
node_modules/http-proxy-middleware/dist/path-filter.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.matchPathFilter = matchPathFilter;
|
||||
const isGlob = require("is-glob");
|
||||
const micromatch = require("micromatch");
|
||||
const url = require("url");
|
||||
const errors_1 = require("./errors");
|
||||
function matchPathFilter(pathFilter = '/', uri, req) {
|
||||
// single path
|
||||
if (isStringPath(pathFilter)) {
|
||||
return matchSingleStringPath(pathFilter, uri);
|
||||
}
|
||||
// single glob path
|
||||
if (isGlobPath(pathFilter)) {
|
||||
return matchSingleGlobPath(pathFilter, uri);
|
||||
}
|
||||
// multi path
|
||||
if (Array.isArray(pathFilter)) {
|
||||
if (pathFilter.every(isStringPath)) {
|
||||
return matchMultiPath(pathFilter, uri);
|
||||
}
|
||||
if (pathFilter.every(isGlobPath)) {
|
||||
return matchMultiGlobPath(pathFilter, uri);
|
||||
}
|
||||
throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY);
|
||||
}
|
||||
// custom matching
|
||||
if (typeof pathFilter === 'function') {
|
||||
const pathname = getUrlPathName(uri);
|
||||
return pathFilter(pathname, req);
|
||||
}
|
||||
throw new Error(errors_1.ERRORS.ERR_CONTEXT_MATCHER_GENERIC);
|
||||
}
|
||||
/**
|
||||
* @param {String} pathFilter '/api'
|
||||
* @param {String} uri 'http://example.org/api/b/c/d.html'
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function matchSingleStringPath(pathFilter, uri) {
|
||||
const pathname = getUrlPathName(uri);
|
||||
return pathname?.indexOf(pathFilter) === 0;
|
||||
}
|
||||
function matchSingleGlobPath(pattern, uri) {
|
||||
const pathname = getUrlPathName(uri);
|
||||
const matches = micromatch([pathname], pattern);
|
||||
return matches && matches.length > 0;
|
||||
}
|
||||
function matchMultiGlobPath(patternList, uri) {
|
||||
return matchSingleGlobPath(patternList, uri);
|
||||
}
|
||||
/**
|
||||
* @param {String} pathFilterList ['/api', '/ajax']
|
||||
* @param {String} uri 'http://example.org/api/b/c/d.html'
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function matchMultiPath(pathFilterList, uri) {
|
||||
let isMultiPath = false;
|
||||
for (const context of pathFilterList) {
|
||||
if (matchSingleStringPath(context, uri)) {
|
||||
isMultiPath = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isMultiPath;
|
||||
}
|
||||
/**
|
||||
* Parses URI and returns RFC 3986 path
|
||||
*
|
||||
* @param {String} uri from req.url
|
||||
* @return {String} RFC 3986 path
|
||||
*/
|
||||
function getUrlPathName(uri) {
|
||||
return uri && url.parse(uri).pathname;
|
||||
}
|
||||
function isStringPath(pathFilter) {
|
||||
return typeof pathFilter === 'string' && !isGlob(pathFilter);
|
||||
}
|
||||
function isGlobPath(pathFilter) {
|
||||
return isGlob(pathFilter);
|
||||
}
|
||||
7
node_modules/http-proxy-middleware/dist/path-rewriter.d.ts
generated
vendored
Normal file
7
node_modules/http-proxy-middleware/dist/path-rewriter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Create rewrite function, to cache parsed rewrite rules.
|
||||
*
|
||||
* @param {Object} rewriteConfig
|
||||
* @return {Function} Function to rewrite paths; This function should accept `path` (request.url) as parameter
|
||||
*/
|
||||
export declare function createPathRewriter(rewriteConfig: any): any;
|
||||
65
node_modules/http-proxy-middleware/dist/path-rewriter.js
generated
vendored
Normal file
65
node_modules/http-proxy-middleware/dist/path-rewriter.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createPathRewriter = createPathRewriter;
|
||||
const is_plain_object_1 = require("is-plain-object");
|
||||
const errors_1 = require("./errors");
|
||||
const debug_1 = require("./debug");
|
||||
const debug = debug_1.Debug.extend('path-rewriter');
|
||||
/**
|
||||
* Create rewrite function, to cache parsed rewrite rules.
|
||||
*
|
||||
* @param {Object} rewriteConfig
|
||||
* @return {Function} Function to rewrite paths; This function should accept `path` (request.url) as parameter
|
||||
*/
|
||||
function createPathRewriter(rewriteConfig) {
|
||||
let rulesCache;
|
||||
if (!isValidRewriteConfig(rewriteConfig)) {
|
||||
return;
|
||||
}
|
||||
if (typeof rewriteConfig === 'function') {
|
||||
const customRewriteFn = rewriteConfig;
|
||||
return customRewriteFn;
|
||||
}
|
||||
else {
|
||||
rulesCache = parsePathRewriteRules(rewriteConfig);
|
||||
return rewritePath;
|
||||
}
|
||||
function rewritePath(path) {
|
||||
let result = path;
|
||||
for (const rule of rulesCache) {
|
||||
if (rule.regex.test(path)) {
|
||||
result = result.replace(rule.regex, rule.value);
|
||||
debug('rewriting path from "%s" to "%s"', path, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
function isValidRewriteConfig(rewriteConfig) {
|
||||
if (typeof rewriteConfig === 'function') {
|
||||
return true;
|
||||
}
|
||||
else if ((0, is_plain_object_1.isPlainObject)(rewriteConfig)) {
|
||||
return Object.keys(rewriteConfig).length !== 0;
|
||||
}
|
||||
else if (rewriteConfig === undefined || rewriteConfig === null) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw new Error(errors_1.ERRORS.ERR_PATH_REWRITER_CONFIG);
|
||||
}
|
||||
}
|
||||
function parsePathRewriteRules(rewriteConfig) {
|
||||
const rules = [];
|
||||
if ((0, is_plain_object_1.isPlainObject)(rewriteConfig)) {
|
||||
for (const [key, value] of Object.entries(rewriteConfig)) {
|
||||
rules.push({
|
||||
regex: new RegExp(key),
|
||||
value: value,
|
||||
});
|
||||
debug('rewrite rule created: "%s" ~> "%s"', key, value);
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
6
node_modules/http-proxy-middleware/dist/plugins/default/debug-proxy-errors-plugin.d.ts
generated
vendored
Normal file
6
node_modules/http-proxy-middleware/dist/plugins/default/debug-proxy-errors-plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Plugin } from '../../types';
|
||||
/**
|
||||
* Subscribe to {@link https://www.npmjs.com/package/http-proxy#listening-for-proxy-events http-proxy error events} to prevent server from crashing.
|
||||
* Errors are logged with {@link https://www.npmjs.com/package/debug debug} library.
|
||||
*/
|
||||
export declare const debugProxyErrorsPlugin: Plugin;
|
||||
61
node_modules/http-proxy-middleware/dist/plugins/default/debug-proxy-errors-plugin.js
generated
vendored
Normal file
61
node_modules/http-proxy-middleware/dist/plugins/default/debug-proxy-errors-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.debugProxyErrorsPlugin = void 0;
|
||||
const debug_1 = require("../../debug");
|
||||
const debug = debug_1.Debug.extend('debug-proxy-errors-plugin');
|
||||
/**
|
||||
* Subscribe to {@link https://www.npmjs.com/package/http-proxy#listening-for-proxy-events http-proxy error events} to prevent server from crashing.
|
||||
* Errors are logged with {@link https://www.npmjs.com/package/debug debug} library.
|
||||
*/
|
||||
const debugProxyErrorsPlugin = (proxyServer) => {
|
||||
/**
|
||||
* http-proxy doesn't handle any errors by default (https://github.com/http-party/node-http-proxy#listening-for-proxy-events)
|
||||
* Prevent server from crashing when http-proxy errors (uncaught errors)
|
||||
*/
|
||||
proxyServer.on('error', (error, req, res, target) => {
|
||||
debug(`http-proxy error event: \n%O`, error);
|
||||
});
|
||||
proxyServer.on('proxyReq', (proxyReq, req, socket) => {
|
||||
socket.on('error', (error) => {
|
||||
debug('Socket error in proxyReq event: \n%O', error);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Fix SSE close events
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/issues/678
|
||||
* @link https://github.com/http-party/node-http-proxy/issues/1520#issue-877626125
|
||||
*/
|
||||
proxyServer.on('proxyRes', (proxyRes, req, res) => {
|
||||
res.on('close', () => {
|
||||
if (!res.writableEnded) {
|
||||
debug('Destroying proxyRes in proxyRes close event');
|
||||
proxyRes.destroy();
|
||||
}
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Fix crash when target server restarts
|
||||
* https://github.com/chimurai/http-proxy-middleware/issues/476#issuecomment-746329030
|
||||
* https://github.com/webpack/webpack-dev-server/issues/1642#issuecomment-790602225
|
||||
*/
|
||||
proxyServer.on('proxyReqWs', (proxyReq, req, socket) => {
|
||||
socket.on('error', (error) => {
|
||||
debug('Socket error in proxyReqWs event: \n%O', error);
|
||||
});
|
||||
});
|
||||
proxyServer.on('open', (proxySocket) => {
|
||||
proxySocket.on('error', (error) => {
|
||||
debug('Socket error in open event: \n%O', error);
|
||||
});
|
||||
});
|
||||
proxyServer.on('close', (req, socket, head) => {
|
||||
socket.on('error', (error) => {
|
||||
debug('Socket error in close event: \n%O', error);
|
||||
});
|
||||
});
|
||||
// https://github.com/webpack/webpack-dev-server/issues/1642#issuecomment-1103136590
|
||||
proxyServer.on('econnreset', (error, req, res, target) => {
|
||||
debug(`http-proxy econnreset event: \n%O`, error);
|
||||
});
|
||||
};
|
||||
exports.debugProxyErrorsPlugin = debugProxyErrorsPlugin;
|
||||
2
node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Plugin } from '../../types';
|
||||
export declare const errorResponsePlugin: Plugin;
|
||||
19
node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.js
generated
vendored
Normal file
19
node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.errorResponsePlugin = void 0;
|
||||
const status_code_1 = require("../../status-code");
|
||||
const errorResponsePlugin = (proxyServer, options) => {
|
||||
proxyServer.on('error', (err, req, res, target) => {
|
||||
// Re-throw error. Not recoverable since req & res are empty.
|
||||
if (!req && !res) {
|
||||
throw err; // "Error: Must provide a proper URL as target"
|
||||
}
|
||||
if ('writeHead' in res && !res.headersSent) {
|
||||
const statusCode = (0, status_code_1.getStatusCode)(err.code);
|
||||
res.writeHead(statusCode);
|
||||
}
|
||||
const host = req.headers && req.headers.host;
|
||||
res.end(`Error occurred while trying to proxy: ${host}${req.url}`);
|
||||
});
|
||||
};
|
||||
exports.errorResponsePlugin = errorResponsePlugin;
|
||||
4
node_modules/http-proxy-middleware/dist/plugins/default/index.d.ts
generated
vendored
Normal file
4
node_modules/http-proxy-middleware/dist/plugins/default/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './debug-proxy-errors-plugin';
|
||||
export * from './error-response-plugin';
|
||||
export * from './logger-plugin';
|
||||
export * from './proxy-events';
|
||||
20
node_modules/http-proxy-middleware/dist/plugins/default/index.js
generated
vendored
Normal file
20
node_modules/http-proxy-middleware/dist/plugins/default/index.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./debug-proxy-errors-plugin"), exports);
|
||||
__exportStar(require("./error-response-plugin"), exports);
|
||||
__exportStar(require("./logger-plugin"), exports);
|
||||
__exportStar(require("./proxy-events"), exports);
|
||||
2
node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.d.ts
generated
vendored
Normal file
2
node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Plugin } from '../../types';
|
||||
export declare const loggerPlugin: Plugin;
|
||||
66
node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.js
generated
vendored
Normal file
66
node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.loggerPlugin = void 0;
|
||||
const url_1 = require("url");
|
||||
const logger_1 = require("../../logger");
|
||||
const logger_plugin_1 = require("../../utils/logger-plugin");
|
||||
const loggerPlugin = (proxyServer, options) => {
|
||||
const logger = (0, logger_1.getLogger)(options);
|
||||
proxyServer.on('error', (err, req, res, target) => {
|
||||
const hostname = req?.headers?.host;
|
||||
const requestHref = `${hostname}${req?.url}`;
|
||||
const targetHref = `${target?.href}`; // target is undefined when websocket errors
|
||||
const errorMessage = '[HPM] Error occurred while proxying request %s to %s [%s] (%s)';
|
||||
const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
|
||||
logger.error(errorMessage, requestHref, targetHref, err.code || err, errReference);
|
||||
});
|
||||
/**
|
||||
* Log request and response
|
||||
* @example
|
||||
* ```shell
|
||||
* [HPM] GET /users/ -> http://jsonplaceholder.typicode.com/users/ [304]
|
||||
* ```
|
||||
*/
|
||||
proxyServer.on('proxyRes', (proxyRes, req, res) => {
|
||||
// BrowserSync uses req.originalUrl
|
||||
// Next.js doesn't have req.baseUrl
|
||||
const originalUrl = req.originalUrl ?? `${req.baseUrl || ''}${req.url}`;
|
||||
// construct targetUrl
|
||||
let target;
|
||||
try {
|
||||
const port = (0, logger_plugin_1.getPort)(proxyRes.req?.agent?.sockets);
|
||||
const obj = {
|
||||
protocol: proxyRes.req.protocol,
|
||||
host: proxyRes.req.host,
|
||||
pathname: proxyRes.req.path,
|
||||
};
|
||||
target = new url_1.URL(`${obj.protocol}//${obj.host}${obj.pathname}`);
|
||||
if (port) {
|
||||
target.port = port;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
}
|
||||
catch (err) {
|
||||
// nock issue (https://github.com/chimurai/http-proxy-middleware/issues/1035)
|
||||
// fallback to old implementation (less correct - without port)
|
||||
target = new url_1.URL(options.target);
|
||||
target.pathname = proxyRes.req.path;
|
||||
}
|
||||
const targetUrl = target.toString();
|
||||
const exchange = `[HPM] ${req.method} ${originalUrl} -> ${targetUrl} [${proxyRes.statusCode}]`;
|
||||
logger.info(exchange);
|
||||
});
|
||||
/**
|
||||
* When client opens WebSocket connection
|
||||
*/
|
||||
proxyServer.on('open', (socket) => {
|
||||
logger.info('[HPM] Client connected: %o', socket.address());
|
||||
});
|
||||
/**
|
||||
* When client closes WebSocket connection
|
||||
*/
|
||||
proxyServer.on('close', (req, proxySocket, proxyHead) => {
|
||||
logger.info('[HPM] Client disconnected: %o', proxySocket.address());
|
||||
});
|
||||
};
|
||||
exports.loggerPlugin = loggerPlugin;
|
||||
22
node_modules/http-proxy-middleware/dist/plugins/default/proxy-events.d.ts
generated
vendored
Normal file
22
node_modules/http-proxy-middleware/dist/plugins/default/proxy-events.d.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Plugin } from '../../types';
|
||||
/**
|
||||
* Implements option.on object to subscribe to http-proxy events.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* on: {
|
||||
* error: (error, req, res, target) => {},
|
||||
* proxyReq: (proxyReq, req, res, options) => {},
|
||||
* proxyReqWs: (proxyReq, req, socket, options) => {},
|
||||
* proxyRes: (proxyRes, req, res) => {},
|
||||
* open: (proxySocket) => {},
|
||||
* close: (proxyRes, proxySocket, proxyHead) => {},
|
||||
* start: (req, res, target) => {},
|
||||
* end: (req, res, proxyRes) => {},
|
||||
* econnreset: (error, req, res, target) => {},
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export declare const proxyEventsPlugin: Plugin;
|
||||
33
node_modules/http-proxy-middleware/dist/plugins/default/proxy-events.js
generated
vendored
Normal file
33
node_modules/http-proxy-middleware/dist/plugins/default/proxy-events.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.proxyEventsPlugin = void 0;
|
||||
const debug_1 = require("../../debug");
|
||||
const function_1 = require("../../utils/function");
|
||||
const debug = debug_1.Debug.extend('proxy-events-plugin');
|
||||
/**
|
||||
* Implements option.on object to subscribe to http-proxy events.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* on: {
|
||||
* error: (error, req, res, target) => {},
|
||||
* proxyReq: (proxyReq, req, res, options) => {},
|
||||
* proxyReqWs: (proxyReq, req, socket, options) => {},
|
||||
* proxyRes: (proxyRes, req, res) => {},
|
||||
* open: (proxySocket) => {},
|
||||
* close: (proxyRes, proxySocket, proxyHead) => {},
|
||||
* start: (req, res, target) => {},
|
||||
* end: (req, res, proxyRes) => {},
|
||||
* econnreset: (error, req, res, target) => {},
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
const proxyEventsPlugin = (proxyServer, options) => {
|
||||
Object.entries(options.on || {}).forEach(([eventName, handler]) => {
|
||||
debug(`register event handler: "${eventName}" -> "${(0, function_1.getFunctionName)(handler)}"`);
|
||||
proxyServer.on(eventName, handler);
|
||||
});
|
||||
};
|
||||
exports.proxyEventsPlugin = proxyEventsPlugin;
|
||||
1
node_modules/http-proxy-middleware/dist/router.d.ts
generated
vendored
Normal file
1
node_modules/http-proxy-middleware/dist/router.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function getTarget(req: any, config: any): Promise<any>;
|
||||
45
node_modules/http-proxy-middleware/dist/router.js
generated
vendored
Normal file
45
node_modules/http-proxy-middleware/dist/router.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getTarget = getTarget;
|
||||
const is_plain_object_1 = require("is-plain-object");
|
||||
const debug_1 = require("./debug");
|
||||
const debug = debug_1.Debug.extend('router');
|
||||
async function getTarget(req, config) {
|
||||
let newTarget;
|
||||
const router = config.router;
|
||||
if ((0, is_plain_object_1.isPlainObject)(router)) {
|
||||
newTarget = getTargetFromProxyTable(req, router);
|
||||
}
|
||||
else if (typeof router === 'function') {
|
||||
newTarget = await router(req);
|
||||
}
|
||||
return newTarget;
|
||||
}
|
||||
function getTargetFromProxyTable(req, table) {
|
||||
let result;
|
||||
const host = req.headers.host;
|
||||
const path = req.url;
|
||||
const hostAndPath = host + path;
|
||||
for (const [key, value] of Object.entries(table)) {
|
||||
if (containsPath(key)) {
|
||||
if (hostAndPath.indexOf(key) > -1) {
|
||||
// match 'localhost:3000/api'
|
||||
result = value;
|
||||
debug('match: "%s" -> "%s"', key, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (key === host) {
|
||||
// match 'localhost:3000'
|
||||
result = value;
|
||||
debug('match: "%s" -> "%s"', host, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function containsPath(v) {
|
||||
return v.indexOf('/') > -1;
|
||||
}
|
||||
1
node_modules/http-proxy-middleware/dist/status-code.d.ts
generated
vendored
Normal file
1
node_modules/http-proxy-middleware/dist/status-code.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function getStatusCode(errorCode: string): number;
|
||||
23
node_modules/http-proxy-middleware/dist/status-code.js
generated
vendored
Normal file
23
node_modules/http-proxy-middleware/dist/status-code.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getStatusCode = getStatusCode;
|
||||
function getStatusCode(errorCode) {
|
||||
let statusCode;
|
||||
if (/HPE_INVALID/.test(errorCode)) {
|
||||
statusCode = 502;
|
||||
}
|
||||
else {
|
||||
switch (errorCode) {
|
||||
case 'ECONNRESET':
|
||||
case 'ENOTFOUND':
|
||||
case 'ECONNREFUSED':
|
||||
case 'ETIMEDOUT':
|
||||
statusCode = 504;
|
||||
break;
|
||||
default:
|
||||
statusCode = 500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return statusCode;
|
||||
}
|
||||
122
node_modules/http-proxy-middleware/dist/types.d.ts
generated
vendored
Normal file
122
node_modules/http-proxy-middleware/dist/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Based on definition by DefinitelyTyped:
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
|
||||
*/
|
||||
import type * as http from 'http';
|
||||
import type * as httpProxy from 'http-proxy';
|
||||
import type * as net from 'net';
|
||||
export type NextFunction<T = (err?: any) => void> = T;
|
||||
export interface RequestHandler<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction> {
|
||||
(req: TReq, res: TRes, next?: TNext): Promise<void>;
|
||||
upgrade: (req: http.IncomingMessage, socket: net.Socket, head: Buffer) => void;
|
||||
}
|
||||
export type Filter<TReq = http.IncomingMessage> = string | string[] | ((pathname: string, req: TReq) => boolean);
|
||||
export interface Plugin<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
|
||||
(proxyServer: httpProxy<TReq, TRes>, options: Options<TReq, TRes>): void;
|
||||
}
|
||||
export interface OnProxyEvent<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
|
||||
error?: httpProxy.ErrorCallback<Error, TReq, TRes>;
|
||||
proxyReq?: httpProxy.ProxyReqCallback<http.ClientRequest, TReq, TRes>;
|
||||
proxyReqWs?: httpProxy.ProxyReqWsCallback<http.ClientRequest, TReq>;
|
||||
proxyRes?: httpProxy.ProxyResCallback<TReq, TRes>;
|
||||
open?: httpProxy.OpenCallback;
|
||||
close?: httpProxy.CloseCallback<TReq>;
|
||||
start?: httpProxy.StartCallback<TReq, TRes>;
|
||||
end?: httpProxy.EndCallback<TReq, TRes>;
|
||||
econnreset?: httpProxy.EconnresetCallback<Error, TReq, TRes>;
|
||||
}
|
||||
export type Logger = Pick<Console, 'info' | 'warn' | 'error'>;
|
||||
export interface Options<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends httpProxy.ServerOptions {
|
||||
/**
|
||||
* Narrow down requests to proxy or not.
|
||||
* Filter on {@link http.IncomingMessage.url `pathname`} which is relative to the proxy's "mounting" point in the server.
|
||||
* Or use the {@link http.IncomingMessage `req`} object for more complex filtering.
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathFilter.md
|
||||
* @since v3.0.0
|
||||
*/
|
||||
pathFilter?: Filter<TReq>;
|
||||
/**
|
||||
* Modify request paths before requests are send to the target.
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* pathRewrite: {
|
||||
* '^/api/old-path': '/api/new-path', // rewrite path
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathRewrite.md
|
||||
*/
|
||||
pathRewrite?: {
|
||||
[regexp: string]: string;
|
||||
} | ((path: string, req: TReq) => string | undefined) | ((path: string, req: TReq) => Promise<string>);
|
||||
/**
|
||||
* Access the internal http-proxy server instance to customize behavior
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* plugins: [(proxyServer, options) => {
|
||||
* proxyServer.on('error', (error, req, res) => {
|
||||
* console.error(error);
|
||||
* });
|
||||
* }]
|
||||
* });
|
||||
* ```
|
||||
* @link https://github.com/chimurai/http-proxy-middleware#plugins-array
|
||||
* @since v3.0.0
|
||||
*/
|
||||
plugins?: Plugin<TReq, TRes>[];
|
||||
/**
|
||||
* Eject pre-configured plugins.
|
||||
* NOTE: register your own error handlers to prevent server from crashing.
|
||||
*
|
||||
* @link https://github.com/chimurai/http-proxy-middleware#ejectplugins-boolean-default-false
|
||||
* @since v3.0.0
|
||||
*/
|
||||
ejectPlugins?: boolean;
|
||||
/**
|
||||
* Listen to http-proxy events
|
||||
* @see {@link OnProxyEvent} for available events
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* on: {
|
||||
* error: (error, req, res, target) => {
|
||||
* console.error(error);
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md
|
||||
* @since v3.0.0
|
||||
*/
|
||||
on?: OnProxyEvent<TReq, TRes>;
|
||||
/**
|
||||
* Dynamically set the {@link Options.target `options.target`}.
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* router: async (req) => {
|
||||
* return 'http://127:0.0.1:3000';
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/router.md
|
||||
*/
|
||||
router?: {
|
||||
[hostOrPath: string]: httpProxy.ServerOptions['target'];
|
||||
} | ((req: TReq) => httpProxy.ServerOptions['target']) | ((req: TReq) => Promise<httpProxy.ServerOptions['target']>);
|
||||
/**
|
||||
* Log information from http-proxy-middleware
|
||||
* @example
|
||||
* ```js
|
||||
* createProxyMiddleware({
|
||||
* logger: console
|
||||
* });
|
||||
* ```
|
||||
* @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md
|
||||
* @since v3.0.0
|
||||
*/
|
||||
logger?: Logger | any;
|
||||
}
|
||||
6
node_modules/http-proxy-middleware/dist/types.js
generated
vendored
Normal file
6
node_modules/http-proxy-middleware/dist/types.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Based on definition by DefinitelyTyped:
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
1
node_modules/http-proxy-middleware/dist/utils/function.d.ts
generated
vendored
Normal file
1
node_modules/http-proxy-middleware/dist/utils/function.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function getFunctionName(fn: Function): string;
|
||||
7
node_modules/http-proxy-middleware/dist/utils/function.js
generated
vendored
Normal file
7
node_modules/http-proxy-middleware/dist/utils/function.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getFunctionName = getFunctionName;
|
||||
function getFunctionName(fn) {
|
||||
return fn.name || '[anonymous Function]';
|
||||
}
|
||||
7
node_modules/http-proxy-middleware/dist/utils/logger-plugin.d.ts
generated
vendored
Normal file
7
node_modules/http-proxy-middleware/dist/utils/logger-plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { Agent } from 'node:http';
|
||||
export type Sockets = Pick<Agent, 'sockets'>;
|
||||
/**
|
||||
* Get port from target
|
||||
* Using proxyRes.req.agent.sockets to determine the target port
|
||||
*/
|
||||
export declare function getPort(sockets?: Sockets): string | undefined;
|
||||
10
node_modules/http-proxy-middleware/dist/utils/logger-plugin.js
generated
vendored
Normal file
10
node_modules/http-proxy-middleware/dist/utils/logger-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPort = getPort;
|
||||
/**
|
||||
* Get port from target
|
||||
* Using proxyRes.req.agent.sockets to determine the target port
|
||||
*/
|
||||
function getPort(sockets) {
|
||||
return Object.keys(sockets || {})?.[0]?.split(':')[1];
|
||||
}
|
||||
107
node_modules/http-proxy-middleware/package.json
generated
vendored
Normal file
107
node_modules/http-proxy-middleware/package.json
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"name": "http-proxy-middleware",
|
||||
"type": "commonjs",
|
||||
"version": "3.0.3",
|
||||
"description": "The one-liner node.js proxy middleware for connect, express, next.js and more",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist coverage tsconfig.tsbuildinfo .eslintcache",
|
||||
"install:all": "yarn && (cd examples && yarn)",
|
||||
"lint": "yarn prettier && yarn eslint",
|
||||
"lint:fix": "yarn prettier:fix && yarn eslint:fix",
|
||||
"eslint": "eslint '{src,test,examples}/**/*.{js,ts}' --cache",
|
||||
"eslint:fix": "yarn eslint --fix",
|
||||
"prettier": "prettier --list-different \"**/*.{js,ts,md,yml,json,html}\"",
|
||||
"prettier:fix": "prettier --write \"**/*.{js,ts,md,yml,json,html}\"",
|
||||
"build": "tsc --build",
|
||||
"test": "jest",
|
||||
"coverage": "jest --coverage",
|
||||
"prepare": "husky",
|
||||
"prepack": "yarn clean && yarn test && yarn build",
|
||||
"spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"
|
||||
},
|
||||
"publishConfig": {
|
||||
"provenance": true
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/chimurai/http-proxy-middleware.git"
|
||||
},
|
||||
"keywords": [
|
||||
"reverse",
|
||||
"proxy",
|
||||
"middleware",
|
||||
"http",
|
||||
"https",
|
||||
"connect",
|
||||
"express",
|
||||
"fastify",
|
||||
"polka",
|
||||
"next.js",
|
||||
"browser-sync",
|
||||
"gulp",
|
||||
"grunt-contrib-connect",
|
||||
"websocket",
|
||||
"ws",
|
||||
"cors"
|
||||
],
|
||||
"author": "Steven Chim",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/chimurai/http-proxy-middleware/issues"
|
||||
},
|
||||
"homepage": "https://github.com/chimurai/http-proxy-middleware#readme",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "19.4.1",
|
||||
"@commitlint/config-conventional": "19.4.1",
|
||||
"@eslint/js": "9.9.1",
|
||||
"@types/debug": "4.1.12",
|
||||
"@types/eslint": "9.6.1",
|
||||
"@types/eslint__js": "8.42.3",
|
||||
"@types/express": "4.17.21",
|
||||
"@types/is-glob": "4.0.4",
|
||||
"@types/jest": "29.5.12",
|
||||
"@types/micromatch": "4.0.9",
|
||||
"@types/node": "22.5.1",
|
||||
"@types/supertest": "6.0.2",
|
||||
"@types/ws": "8.5.12",
|
||||
"body-parser": "1.20.2",
|
||||
"eslint": "9.9.1",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-prettier": "5.2.1",
|
||||
"express": "4.19.2",
|
||||
"get-port": "5.1.1",
|
||||
"globals": "15.9.0",
|
||||
"husky": "9.1.5",
|
||||
"jest": "29.7.0",
|
||||
"lint-staged": "15.2.9",
|
||||
"mockttp": "3.15.2",
|
||||
"open": "8.4.2",
|
||||
"prettier": "3.3.3",
|
||||
"supertest": "7.0.0",
|
||||
"ts-jest": "29.2.5",
|
||||
"typescript": "5.5.4",
|
||||
"typescript-eslint": "8.3.0",
|
||||
"ws": "8.18.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/http-proxy": "^1.17.15",
|
||||
"debug": "^4.3.6",
|
||||
"http-proxy": "^1.18.1",
|
||||
"is-glob": "^4.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"micromatch": "^4.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"commitlint": {
|
||||
"extends": [
|
||||
"@commitlint/config-conventional"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user