@qiwi/qorsproxy
v4.1.1
Published
HTTP(S) proxy for dev purposes
Downloads
21
Readme
qorsproxy
~~Cors~~ http(s) proxy for ~~dev~~ any purposes
Install
# npm
npm i qorsproxy --save-dev
# yarn
yarn add -D qorsproxy
or just run via npx
/ npm exec
:
npx qorsproxy [options]
Start
qorsproxy -p 8080 -c /Users/a.golub/repo/qorsproxy/config/qorsproxy.dev.qiwi.tools.json
or via runners:
npm start -- --config=path
pm2 start npm --name qorsproxy -- start -- --port=8080 --config=/Users/a.golub/repo/qorsproxy/config/qorsproxy.dev.qiwi.tools.json
npm run start:pm2 -- -- --port=8080
{"message":"[email protected] is loading...","level":"info"}
{"message":"argv={}","level":"info"}
{"message":"Config path=<empty>","level":"info"}
{"message":"Config ready.","level":"info"}
{"message":"Container configured.","level":"info"}
{"message":"Container is online: http://localhost:9292, https://localhost:9293","level":"info"}
Usage
curl 'http://127.0.0.1:9292/http://example.com' -H 'origin:http://localhost' → <!doctype html> ...
Configuration
JS/TS API
import {App} from 'qorsproxy'
const options = {
config: 'path/to/config.json', // or plain object
watch: true, // if true, config would be reloaded on change
port: 9292, // http port. Optional
host: 'localhost', // http host. Optional
}
const orchestrator = App.main(options)
// later
orchestrator.config.update({server: {port: 8080}, ...rest})
// ...
await orchestrator.container.stop()
CLI
--host
,-h
DNS name or IP address. Defaults tolocalhost
.--port
,-p
defines exposed port. Defaults to9292
.--secure.port
, defines exposed secure port. Defaults to9293
.--secure.cert
, path to SSL certificate. Defaults to certificate inssl/cert.pem
.--secure.key
, path to SSL private key. Defaults to key inssl/cert.pem
.--config
,-c
sets path to the custom config.--watch
,-w
if defined setsfs.watchFile
interval for config update. Ifport
orhost
has been changed, the server would be restarted. If config becomes invalid, the prev working version remains applied.
JSON / YAML
At the top level config describes server
, log
and proxy rules
sections.
rules
is the main one
It declares allowed connections and their side-effects like mutations
, interceptions
, customAuthorization
and etc.
Qorsproxy applies the first matched rule to the request, therefore declaration order matters.
rules
may be declared as a map:
{
"rules": {
"localhost": {
"from": [
"*"
],
"to": [
"example.com"
],
"paths": [
"/"
],
"mutations": [
{
"direction": "to",
"headers": [
{
"name": "origin",
"value": "localhost"
}
]
},
{
"direction": "from",
"headers": [
{
"name": "set-cookie",
"value": {
"from": "/;Domain.+;/",
"to": ";Domain: foobar.com;"
}
}
]
}
]
}
}
}
array syntax is suitable too:
{
"rules": [
{
"from": [
"*"
],
"to": [
"example.com"
]
}
]
}
log
Winston is under the hood and you're able to set some parameters:
{
"log": {
"dir": "./logs/",
"filename": "qors-%DATE%.log",
"datePattern": "YYYY-MM-DD",
"size": 52428800,
"level": "info"
}
}
server
{
"server": {
"host": "127.0.0.1",
"port": 8080,
"cert": "/path/to/cert.pem", // Defaults to ./ssl/cert.pem
"key": "/path/to/key.pem" // and ./ssl/key.pem
}
}
Pre-flight
If you need support for OPTIONS request, extend target rule:
"interceptions": [
{
"req": {
"method": "OPTIONS"
},
"res": {
"status": 200
}
}
],
Authorization
If intermediate authorization is required (change auth for JWT) add customAuthorization
to the target rule. See details at schema and impl.
"customAuthorization": {
"targetUrl": "example.com",
"authorizationUrl": "example-authorization.com",
"headers": ["authorization", "cookie"],
"authPath": "Edge.Headers.Authorization[0]"
}
Cypress
Cypress has a trouble with Transfer-Encoding: chunked
header, so in this case you may use a workaround:
{
"mutations": [
{
"direction": "from",
"headers": [
{
"name": "transfer-encoding",
"value": null
}
]
}
]
}
Monitoring
There are several features to clarify what's going on with proxy.
GET /health
Exposes liveness probe.
{
"status":"UP",
"critical":true,
"deps":{
"corsproxy":{
"status":"UP",
"critical":true
}
}
}
GET /metrics
Uptime, CPU and memory usage, request counter:
{
"process": {
"uptime": "00:10:29",
"memory": {"rss": 96956416, "heapTotal": 56356864, "heapUsed": 47617368, "external": 10413906},
"cpu": {"user": 2229086, "system": 585411}
},
"servlets": {
"corsproxy": {
"count": 3,
"traffic": 1270
}
}
}
GET /info
Common app info: version, name, etc.
{
"name": "qorsproxy",
"version": "1.5.4",
"description": "Cors proxy for dev purposes",
"repository": "[email protected]:qiwi/qorsproxy.git"
}
Alternatives
- Get any from google
- Write your own.
const http = require('http');
http.createServer(handler).listen(3000);
function handler(req, res) {
console.log('serve: ' + req.url);
const options = {
hostname: 'example.com',
port: 80,
path: req.url,
method: req.method
};
const proxy = http.request(options, _res => {
_res.pipe(res, {
end: true
});
});
req.pipe(proxy, {
end: true
});
}