4.1.1 • Published 10 months ago

qorsproxy v4.1.1

Weekly downloads
16
License
MIT
Repository
github
Last release
10 months ago

qorsproxy

Cors http(s) proxy for dev any purposes

CI Maintainability Test Coverage npm (tag)

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":"Qorsproxy@2.4.10 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 to localhost.
  • --port, -p defines exposed port. Defaults to 9292.
  • --secure.port, defines exposed secure port. Defaults to 9293.
  • --secure.cert, path to SSL certificate. Defaults to certificate in ssl/cert.pem.
  • --secure.key, path to SSL private key. Defaults to key in ssl/cert.pem.
  • --config, -c sets path to the custom config.
  • --watch, -w if defined sets fs.watchFile interval for config update. If port or host 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": "git@github.com:qiwi/qorsproxy.git"
}

Alternatives

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
	});
}

License

MIT

4.1.1

10 months ago

4.1.0

1 year ago

4.0.11

1 year ago

4.0.10

2 years ago

4.0.9

2 years ago

4.0.4

2 years ago

4.0.1

2 years ago

4.0.3

2 years ago

4.0.2

2 years ago

3.2.1

2 years ago

3.2.0

2 years ago

3.0.1

2 years ago

4.0.0

2 years ago

3.1.0

2 years ago

2.4.19

3 years ago

3.0.0

3 years ago

2.4.18

3 years ago

2.4.17

3 years ago

2.4.16

3 years ago

2.4.14

3 years ago

2.4.13

3 years ago

2.4.15

3 years ago

2.4.12

4 years ago

2.4.10

4 years ago

2.4.11

4 years ago

2.4.9

4 years ago

2.4.8

4 years ago

2.4.7

4 years ago

2.4.6

4 years ago

2.4.5

4 years ago

2.4.4

5 years ago

2.4.3

5 years ago

2.4.2

5 years ago

2.4.1

5 years ago

2.4.0

5 years ago

2.3.0

5 years ago

2.2.1

5 years ago

2.2.0

6 years ago

2.1.0

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.5.4

6 years ago

1.5.3

6 years ago

1.5.2

6 years ago

1.5.1

6 years ago

1.5.0

6 years ago

1.4.1

6 years ago

1.4.0

7 years ago

1.3.1

7 years ago

1.3.0

7 years ago

1.2.2

7 years ago

1.2.1

7 years ago

1.2.0

7 years ago

1.1.1

7 years ago

1.1.0

7 years ago

1.0.0

7 years ago