Skip to content

Commit 0716bf0

Browse files
authored
Merge pull request #47 from AVierwind/master
Add simple proxy
2 parents e40b67c + c9d0392 commit 0716bf0

File tree

7 files changed

+571
-13
lines changed

7 files changed

+571
-13
lines changed

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,43 @@ module.exports = (argv) => {
111111
};
112112
```
113113

114+
## Http proxy
115+
116+
#### Enabling proxy
117+
118+
The server contains a simple http proxy.
119+
The proxy must be configured in the config file.
120+
To enable this proxy:
121+
122+
```sh
123+
angular-http-server --config configs/angular-http-server.config.js --useProxy true
124+
```
125+
126+
#### configuring proxy
127+
128+
To configure the proxy add a proxy object to your config file.
129+
The proxy should be an array of configs with two required properties: a forward property which must be a string array listing url parts which should trigger the proxy, and a target property which should define the target to proxy to.
130+
The config can also contain an optional protocol option, when this is absent the server will default to https
131+
132+
simple example:
133+
134+
```js
135+
module.exports = {
136+
proxy: [
137+
{
138+
forward: ['api/example-api', 'api-proxy/example'],
139+
target: 'localhost:5000',
140+
protocol: 'http'
141+
},
142+
{
143+
forward: ['api/example-api-2', 'api-proxy-2/example'],
144+
target: 'localhost:6000',
145+
}
146+
],
147+
};
148+
```
149+
150+
114151
## Self-Signed HTTPS Use
115152

116153
#### Production

example/config/config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
proxy: [
3+
{
4+
forward: ['beach.jpg', 'api-proxy/example'],
5+
target: 'www.google.nl',
6+
},
7+
{
8+
forward: ['api/example-api-2', 'image.svg'],
9+
target: 'www.github.com',
10+
protocol: 'http'
11+
},
12+
],
13+
};

lib/angular-http-server.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var opn = require("opn");
1010

1111
var argv = require("minimist")(process.argv.slice(2));
1212
const getFilePathFromUrl = require('./get-file-path-from-url');
13+
const proxyHandler = require("./proxy");
1314

1415
// Pre-process arguments
1516
const useHttps = argv.ssl || argv.https;
@@ -84,6 +85,10 @@ function start() {
8485
// HELPERS
8586

8687
function requestListener(req, res) {
88+
// When we hit the proxy, return
89+
if (argv.proxy && proxyHandler(req, res, argv.proxy)) {
90+
return;
91+
}
8792
// Add CORS header if option chosen
8893
if (argv.cors) {
8994
res.setHeader("Access-Control-Allow-Origin", "*");

lib/proxy.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const httpProxy = require("http-proxy");
2+
3+
var proxyServer = null;
4+
5+
/**
6+
* Simple Http Proxy, proxies request where url is contained in config to target from config
7+
*
8+
* @param req
9+
* @param res
10+
* @param {object} configs - proxyConfig from config file
11+
* @return {boolean} - will return whether request is being proxied
12+
*/
13+
function proxyHandler(req, res, configs) {
14+
if (!configs || configs.length === 0) {
15+
throw new Error(
16+
"no proxy configs present, please configure in your config file"
17+
);
18+
}
19+
let proxyHit = false;
20+
configs.forEach((config) => {
21+
if (!proxyHit) {
22+
if (!config.forward || config.forward.length === 0) {
23+
throw new Error(
24+
"forward is missing or empty in your proxyConfig"
25+
);
26+
}
27+
28+
if (!config.target || config.target === "") {
29+
throw new Error(
30+
"target is missing or empty in your proxyConfig"
31+
);
32+
}
33+
34+
proxyHit = config.forward.some(
35+
(url) => req.url.indexOf(url) !== -1
36+
);
37+
if (proxyHit) {
38+
const protocol = config.protocol ? config.protocol : "https";
39+
console.log(
40+
`Proxying request ${req.method}, ${req.url} to ${protocol}://${config.target}`
41+
);
42+
43+
if (proxyServer === null) {
44+
proxyServer = httpProxy.createProxyServer({});
45+
}
46+
47+
proxyServer.web(req, res, {
48+
target: `${protocol}://${config.target}`,
49+
});
50+
}
51+
}
52+
});
53+
return proxyHit;
54+
}
55+
56+
module.exports = proxyHandler;

lib/proxy.spec.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const { expect } = require("chai");
2+
const proxyHandler = require("./proxy");
3+
const httpMock = require("node-mocks-http");
4+
5+
describe("proxyHandler", () => {
6+
it("should not proxy request to target when url from forward is not present", () => {
7+
const config = [
8+
{
9+
forward: ["sample", "proxy-this"],
10+
target: "www.github.com",
11+
},
12+
];
13+
const req = httpMock.createRequest({
14+
method: "GET",
15+
url: "https://localhost:4200/proxyTest",
16+
pipe: () => {},
17+
});
18+
19+
expect(proxyHandler(req, {}, config, false)).to.equal(false);
20+
});
21+
22+
it("should proxy request to target when url from forward is present", () => {
23+
const config = [
24+
{
25+
forward: ["sample", "proxy-this"],
26+
target: "www.github.com",
27+
},
28+
];
29+
const req = httpMock.createRequest({
30+
method: "GET",
31+
url: "https://localhost:4200/proxyTest/proxy-this",
32+
pipe: () => {},
33+
});
34+
35+
expect(proxyHandler(req, {}, config, false)).to.equal(true);
36+
});
37+
38+
it("should throw error when no config present", () => {
39+
config = [];
40+
const req = httpMock.createRequest({
41+
method: "GET",
42+
url: "https://localhost:4200/proxyTest/proxy-this",
43+
pipe: () => {},
44+
});
45+
46+
expect(() => proxyHandler(req, {}, null, false)).to.throw(
47+
"no proxyConfig present, please configure in your config file"
48+
);
49+
});
50+
51+
it("should throw error when forward is missing", () => {
52+
const config = [
53+
{
54+
forward: [],
55+
target: "www.github.com",
56+
},
57+
];
58+
const req = httpMock.createRequest({
59+
method: "GET",
60+
url: "https://localhost:4200/proxyTest/proxy-this",
61+
pipe: () => {},
62+
});
63+
64+
expect(() => proxyHandler(req, {}, config, false)).to.throw(
65+
"forward is missing or empty in your proxyConfig"
66+
);
67+
});
68+
it("should throw error when target is missing", () => {
69+
const config = [
70+
{
71+
forward: ["sample", "proxy-this"],
72+
target: "",
73+
},
74+
];
75+
const req = httpMock.createRequest({
76+
method: "GET",
77+
url: "https://localhost:4200/proxyTest/proxy-this",
78+
pipe: () => {},
79+
});
80+
81+
expect(() => proxyHandler(req, {}, config, false)).to.throw(
82+
"target is missing or empty in your proxyConfig"
83+
);
84+
});
85+
});

0 commit comments

Comments
 (0)