- Notifications
You must be signed in to change notification settings - Fork0
⚡ The one-liner node.js http2-proxy middleware for koa
License
hvdb/koa-http2-proxy
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Configurehttp2-proxy middleware with ease forkoa.
Based onhttp-proxy-middleware.
Proxy requests tohttp://www.example.org
varKoa=require('koa');varproxy=require('koa-http2-proxy');varapp=newKoa();// responseapp.use(proxy({target:'http://www.example.org'}));app.listen(3000);// http://localhost:3000/foo/bar -> http://www.example.org/foo/bar
💡Tip: Set the optionchangeOrigin
totrue
forname-based virtual hosted sites.
$npminstall--save-devkoa-http2-proxy
Proxy middleware configuration.
varproxy=require('koa-http2-proxy');varapiProxy=proxy('/api',{target:'http://www.example.org'});// \____/ \_____________________________/// | |// context options// 'apiProxy' is now ready to be used as middleware in a server.
- context: Determine which requests should be proxied to the target host.(more oncontext matching)
- options.target: target host to proxy to.(protocol + host)
(full list ofkoa-http2-proxy
configuration options)
// shorthand syntax for the example above:varapiProxy=proxy('http://www.example.org/api');
More about theshorthand configuration.
// include dependenciesvarKoa=require('koa');varproxy=require('koa-http2-proxy');// proxy middleware optionsvaroptions={target:'http://www.example.org',// target hostws:true,// proxy websocketspathRewrite:{'^/api/old-path':'/api/new-path',// rewrite path'^/api/remove/path':'/path'// remove base path},router:{// when request.headers.host == 'dev.localhost:3000',// override target 'http://www.example.org' to 'http://localhost:8000''dev.localhost:3000':'http://localhost:8000'}};// create the proxy (without context)varexampleProxy=proxy(options);// mount `exampleProxy` in web servervarapp=newKoa();app.use(exampleProxy);app.listen(3000);
Providing an alternative way to decide which requests should be proxied; In case you are not able to use the server'spath
parameter to mount the proxy or when you need more flexibility.
RFC 3986path
is used for context matching.
foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment
path matching
proxy({...})
- matches any path, all requests will be proxied.proxy('/', {...})
- matches any path, all requests will be proxied.proxy('/api', {...})
- matches paths starting with/api
multiple path matching
proxy(['/api', '/ajax', '/someotherpath'], {...})
wildcard path matching
For fine-grained control you can use wildcard matching. Glob pattern matching is done bymicromatch. Visitmicromatch orglob for more globbing examples.
proxy('**', {...})
matches any path, all requests will be proxied.proxy('**/*.html', {...})
matches any path which ends with.html
proxy('/*.html', {...})
matches paths directly under path-absoluteproxy('/api/**/*.html', {...})
matches requests ending with.html
in the path of/api
proxy(['/api/**', '/ajax/**'], {...})
combine multiple patternsproxy(['/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.
/** *@return {Boolean} */varfilter=function(pathname,req){returnpathname.match('^/api')&&req.method==='GET';};varapiProxy=proxy(filter,{target:'http://www.example.org'});
option.pathRewrite: object/function, rewrite target's url path. Object-keys will be used asRegExp to match paths.
// rewrite pathpathRewrite:{'^/old/api' :'/new/api'}// remove pathpathRewrite:{'^/remove/api' :''}// add base pathpathRewrite:{'^/' :'/basepath/'}// custom rewritingpathRewrite:function(path,req){returnpath.replace('/api','/base/api')}
option.router: object/function, re-target
option.target
for specific requests.// Use `host` and/or `path` to match requests. First match will be used.// The order of the configuration matters.router:{'integration.localhost:3000' :'http://localhost:8001',// host only'staging.localhost:3000' :'http://localhost:8002',// host only'localhost:3000/api' :'http://localhost:8003',// host + path'/rest' :'http://localhost:8004'// path only}// Custom router functionrouter:function(req){return'http://localhost:8004';}
option.logLevel: string, ['debug', 'info', 'warn', 'error', 'silent']. Default:
'info'
option.logProvider: function, modify or replace log provider. Default:
console
.// simple replacefunctionlogProvider(provider){// replace the default console log provider.returnrequire('winston');}
// verbose replacementfunctionlogProvider(provider){varlogger=new(require('winston')).Logger();varmyCustomProvider={log:logger.log,debug:logger.debug,info:logger.info,warn:logger.warn,error:logger.error};returnmyCustomProvider;}
option.onError: function, subscribe to http-proxy's
error
event for custom error handling.functiononError(err,ctx){ctx.response.status=500;ctx.response.body='Something went wrong. And we are reporting a custom error message.';}
option.onProxyRes: function, subscribe to http-proxy's
proxyRes
event.functiononProxyRes(proxyRes,ctx){proxyRes.headers['x-added']='foobar';// add new header to responsedeleteproxyRes.headers['x-removed'];// remove header from response}
option.onProxyReq: function, subscribe to http-proxy's
proxyReq
event.functiononProxyReq(proxyReq,ctx){// add custom header to requestproxyReq.setHeader('x-added','foobar');// or log the req}
option.onUpgrade: function, called before upgrading a websocket connection.
onUpgrade:asyncctx=>{// add session middleware to the websocket connection// see option.appawaitsession(ctx,()=>{});};
option.app: koa app, used to generate a koa ctx to be used in onUpgrade. If left blank, a object containing only
req
will be used as contextoption.headers: object, addsrequest headers. (Example:
{host:'www.example.org'}
)option.target: url string to be parsed with the url module
option.ws: true/false: if you want to proxy websockets
option.xfwd: true/false, adds x-forward headers
option.changeOrigin: true/false, Default: false - changes the origin of the host header to the target URL
option.proxyTimeout: timeout (in millis) when proxy receives no response from target
option.proxyName: Proxy name used for Via header
Use the shorthand syntax when verbose configuration is not needed. Thecontext
andoption.target
will be automatically configured when shorthand is used. Options can still be used if needed.
proxy('http://www.example.org:8000/api');// proxy('/api', {target: 'http://www.example.org:8000'});proxy('http://www.example.org:8000/api/books/*/**.json');// proxy('/api/books/*/**.json', {target: 'http://www.example.org:8000'});proxy('http://www.example.org:8000/api');// proxy('/api', {target: 'http://www.example.org:8000'});
// verbose apiproxy('/',{target:'http://echo.websocket.org',ws:true});// shorthandproxy('http://echo.websocket.org',{ws:true});// shorter shorthandproxy('ws://echo.websocket.org');
In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the httpupgrade
event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's httpupgrade
event manually.
varwsProxy=proxy('ws://echo.websocket.org');varapp=newKoa();app.use(wsProxy);varserver=app.listen(3000);server.on('upgrade',wsProxy.upgrade);// <-- subscribe to http 'upgrade'
Run the test suite:
# install dependencies$ yarn# linting$ yarn lint$ yarn lint:fix# building (compile typescript to js)$ yarn build# unit tests$ yarntest# code coverage$ yarn cover
The MIT License (MIT)
Copyright for portions of this project are held by Steven Chim, 2015-2019 as part ofhttp-proxy-middleware. All other copyright for this project are held by Ontola BV, 2019.
About
⚡ The one-liner node.js http2-proxy middleware for koa
Resources
License
Stars
Watchers
Forks
Packages0
Languages
- TypeScript99.9%
- JavaScript0.1%