@cloud-cli/px 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -12
- package/dist/proxy.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# PX
|
|
2
2
|
|
|
3
|
-
Reverse proxy to map local services
|
|
3
|
+
Reverse proxy to map local services and external http(s) domains
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Usage
|
|
6
6
|
|
|
7
7
|
Use it with [Cloudy](https://github.com/cloud-cli/cli)
|
|
8
8
|
|
|
@@ -14,11 +14,11 @@ import proxy from '@cloud-cli/px';
|
|
|
14
14
|
export default { proxy };
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## API
|
|
18
18
|
|
|
19
19
|
**Add a proxy to a local service**
|
|
20
20
|
|
|
21
|
-
```
|
|
21
|
+
```bash
|
|
22
22
|
cy proxy.add --domain "foo.example.com" --target "http://localhost:1234"
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -26,42 +26,43 @@ All available options:
|
|
|
26
26
|
|
|
27
27
|
- `domain`: entrypoint for reverse proxy
|
|
28
28
|
- `target`: any target for requests, can be local or remote
|
|
29
|
+
- `cors`: handle CORS request on proxy level. See notes below!
|
|
29
30
|
- `redirect`: if request comes as http, redirect to https
|
|
30
31
|
- `redirectUrl`: if provided, issues a `Location` header and terminates with status 302 instead of proxying a request
|
|
31
32
|
|
|
32
33
|
**Remove a proxy**
|
|
33
34
|
|
|
34
|
-
```
|
|
35
|
+
```bash
|
|
35
36
|
cy proxy.remove --domain "foo.example.com"
|
|
36
37
|
```
|
|
37
38
|
|
|
38
39
|
**Get details of a proxy**
|
|
39
40
|
|
|
40
|
-
```
|
|
41
|
+
```bash
|
|
41
42
|
cy proxy.get --domain "foo.example.com"
|
|
42
43
|
```
|
|
43
44
|
|
|
44
45
|
**List proxies**
|
|
45
46
|
|
|
46
|
-
```
|
|
47
|
+
```bash
|
|
47
48
|
cy proxy.list
|
|
48
49
|
```
|
|
49
50
|
|
|
50
51
|
**List registered domains**
|
|
51
52
|
|
|
52
|
-
```
|
|
53
|
+
```bash
|
|
53
54
|
cy proxy.domains
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
**Reload all configurations**
|
|
57
58
|
|
|
58
|
-
```
|
|
59
|
+
```bash
|
|
59
60
|
cy proxy.reload
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
## Certificate file resolution
|
|
63
64
|
|
|
64
|
-
```
|
|
65
|
+
```bash
|
|
65
66
|
certificatesFolder = '/etc/letsencrypt/live' or process.env.PX_CERTS_FOLDER
|
|
66
67
|
rootDomain = 'example.com' in 'xyz.example.com'
|
|
67
68
|
cert = certificatesFolder + '/' + rootDomain + '/' + certificateFile
|
|
@@ -70,7 +71,20 @@ key = certificatesFolder + '/' + rootDomain + '/' + keyFile
|
|
|
70
71
|
|
|
71
72
|
So xyz.example.com points to:
|
|
72
73
|
|
|
73
|
-
```
|
|
74
|
+
```bash
|
|
74
75
|
/etc/letsencrypt/live/example.com/fullchain.pem for certificate
|
|
75
76
|
/etc/letsencrypt/live/example.com/privkey.pem for private key
|
|
76
77
|
```
|
|
78
|
+
|
|
79
|
+
## Notes
|
|
80
|
+
|
|
81
|
+
CORS handling on proxy level is convenient, **but a security risk**. Beware:
|
|
82
|
+
|
|
83
|
+
- All origins are allowed, all common methods and headers, and credentials are enabled.
|
|
84
|
+
- In case of an `OPTIONS` request, if coming via CORS (a preflight), an empty response will be send and the request ends before calling the proxied target.
|
|
85
|
+
|
|
86
|
+
Every request has 2 additional headers:
|
|
87
|
+
|
|
88
|
+
- x-forwarded-for: the host of the original request.
|
|
89
|
+
If a proxy is from 'https://foo.example.com' to 'http://localhost:1234', the header will be 'foo.example.com'
|
|
90
|
+
- x-forwarded-proto: 'http:' or 'https:', depends on the original request
|
package/dist/proxy.js
CHANGED
|
@@ -68,7 +68,9 @@ export class ProxyServer {
|
|
|
68
68
|
return status.isDirectory() ? dir : '';
|
|
69
69
|
}));
|
|
70
70
|
folders.filter(Boolean).forEach(async (rootDomain) => {
|
|
71
|
-
|
|
71
|
+
if (process.env.DEBUG) {
|
|
72
|
+
console.log(`Loading certificate for ${rootDomain}`);
|
|
73
|
+
}
|
|
72
74
|
certs[rootDomain] = createSecureContext({
|
|
73
75
|
cert: await readFile(join(certificatesFolder, rootDomain, certificateFile), 'utf8'),
|
|
74
76
|
key: await readFile(join(certificatesFolder, rootDomain, keyFile), 'utf8'),
|
|
@@ -114,6 +116,7 @@ export class ProxyServer {
|
|
|
114
116
|
setHeaders(req, proxyRequest);
|
|
115
117
|
proxyRequest.setHeader('host', getHost(target));
|
|
116
118
|
proxyRequest.setHeader('x-forwarded-for', req.headers.host);
|
|
119
|
+
proxyRequest.setHeader('x-forwarded-proto', insecure ? 'http:' : 'https:');
|
|
117
120
|
req.on('data', (chunk) => proxyRequest.write(chunk));
|
|
118
121
|
req.on('end', () => proxyRequest.end());
|
|
119
122
|
proxyRequest.on('error', (error) => handleError(error, res));
|
|
@@ -161,7 +164,7 @@ function setHeaders(from, to) {
|
|
|
161
164
|
}
|
|
162
165
|
}
|
|
163
166
|
function handleError(error, res) {
|
|
164
|
-
console.
|
|
167
|
+
console.error(error);
|
|
165
168
|
if (error.code === 'ECONNREFUSED') {
|
|
166
169
|
res.writeHead(502);
|
|
167
170
|
res.end();
|