Skip to content

Commit 271818d

Browse files
committed
feat: refactored and improved API, better certbot support
1 parent a3bb218 commit 271818d

File tree

5 files changed

+5374
-3201
lines changed

5 files changed

+5374
-3201
lines changed

README.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,7 @@ yarn add @ladjs/proxy
3535

3636
## Usage
3737

38-
```js
39-
#!/usr/bin/env node
40-
const proxy = require('@ladjs/proxy');
41-
42-
proxy.listen('127.0.0.1', 80);
43-
```
38+
See <https://github.com/ladjs/lad/blob/master/template/proxy.js> for the most up to date usage example.
4439

4540

4641
## Contributors
@@ -55,7 +50,7 @@ proxy.listen('127.0.0.1', 80);
5550
[MIT](LICENSE) © [Nick Baugh](http://niftylettuce.com/)
5651

5752

58-
##
53+
##
5954

6055
[npm]: https://www.npmjs.com/
6156

index.js

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,62 @@
11
const http = require('http');
2-
const url = require('url');
2+
const util = require('util');
33

4-
const proxy = http.createServer((req, res) => {
5-
res.writeHead(301, {
6-
Location: url.parse(`https://${req.headers.host}${req.url}`).href
7-
});
4+
const Router = require('router');
5+
const _ = require('lodash');
6+
const finalhandler = require('finalhandler');
7+
const parse = require('url-parse');
88

9-
res.end();
10-
});
9+
class ProxyServer {
10+
constructor(config) {
11+
this.config = {
12+
logger: console,
13+
port: process.env.PROXY_PORT || null,
14+
certbot: {
15+
name: process.env.CERTBOT_WELL_KNOWN_NAME || null,
16+
contents: process.env.CERTBOT_WELL_KNOWN_CONTENTS || null
17+
},
18+
...config
19+
};
1120

12-
if (!module.parent) proxy.listen(80);
21+
const router = new Router();
1322

14-
module.exports = proxy;
23+
// support for lets encrypt verification
24+
if (
25+
_.isObject(this.config.certbot) &&
26+
_.isString(this.config.certbot.name) &&
27+
_.isString(this.config.certbot.contents)
28+
)
29+
router.get(
30+
`/.well-known/acme-challenge/${this.config.certbot.name}`,
31+
(req, res) => {
32+
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
33+
res.end(this.config.certbot.contents);
34+
}
35+
);
36+
37+
router.use((req, res) => {
38+
res.writeHead(301, {
39+
Location: parse(`https://${req.headers.host}${req.url}`).href
40+
});
41+
res.end();
42+
});
43+
44+
this.server = http.createServer((req, res) => {
45+
router(req, res, finalhandler(req, res));
46+
});
47+
48+
// bind listen/close to this
49+
this.listen = this.listen.bind(this);
50+
this.close = this.close.bind(this);
51+
}
52+
53+
async listen(port) {
54+
await util.promisify(this.server.listen).bind(this.server)(port);
55+
}
56+
57+
async close() {
58+
await util.promisify(this.server.close).bind(this.server);
59+
}
60+
}
61+
62+
module.exports = ProxyServer;

package.json

Lines changed: 77 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,73 +3,108 @@
33
"description": "Proxy for Lad",
44
"version": "0.0.1",
55
"author": "Nick Baugh <[email protected]> (http://niftylettuce.com/)",
6+
"ava": {
7+
"failFast": true,
8+
"verbose": true
9+
},
610
"bugs": {
711
"url": "https://github.com/ladjs/proxy/issues",
812
"email": "[email protected]"
913
},
14+
"commitlint": {
15+
"extends": [
16+
"@commitlint/config-conventional"
17+
]
18+
},
1019
"contributors": [
1120
"Nick Baugh <[email protected]> (http://niftylettuce.com/)"
1221
],
13-
"dependencies": {},
14-
"ava": {
15-
"failFast": true,
16-
"verbose": true
22+
"dependencies": {
23+
"finalhandler": "^1.1.2",
24+
"lodash": "^4.17.15",
25+
"router": "^1.3.3",
26+
"url-parse": "^1.4.7"
1727
},
1828
"devDependencies": {
19-
"ava": "^0.22.0",
20-
"codecov": "^2.3.0",
21-
"cross-env": "^5.0.5",
22-
"eslint": "^4.5.0",
23-
"eslint-config-prettier": "^2.3.0",
24-
"eslint-plugin-prettier": "^2.2.0",
25-
"husky": "^0.14.3",
26-
"lint-staged": "^4.0.4",
27-
"nyc": "^11.1.0",
28-
"prettier": "^1.6.1",
29-
"remark-cli": "^4.0.0",
30-
"remark-preset-github": "^0.0.6",
31-
"xo": "^0.19.0"
29+
"@commitlint/cli": "^8.1.0",
30+
"@commitlint/config-conventional": "^8.1.0",
31+
"ava": "^2.3.0",
32+
"codecov": "^3.5.0",
33+
"cross-env": "^5.2.1",
34+
"eslint": "^6.3.0",
35+
"eslint-config-xo-lass": "^1.0.3",
36+
"fixpack": "^2.3.1",
37+
"husky": "^3.0.5",
38+
"lint-staged": "^9.2.5",
39+
"nyc": "^14.1.1",
40+
"remark-cli": "^7.0.0",
41+
"remark-preset-github": "^0.0.16",
42+
"supertest": "^4.0.2",
43+
"xo": "^0.24.0"
3244
},
3345
"engines": {
3446
"node": ">=8.3"
3547
},
3648
"homepage": "https://github.com/ladjs/proxy",
49+
"husky": {
50+
"hooks": {
51+
"pre-commit": "lint-staged && npm test",
52+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
53+
}
54+
},
3755
"keywords": [
38-
"proxy",
39-
"lad",
40-
"koa",
41-
"http",
42-
"handler",
43-
"nginx",
44-
"reverse",
45-
"https",
46-
"hosts",
47-
"host",
4856
"config",
57+
"domain",
58+
"domains",
59+
"encrypted",
4960
"forward",
50-
"port",
5161
"forwarding",
62+
"handler",
63+
"host",
64+
"hosts",
65+
"http",
66+
"https",
67+
"koa",
68+
"lad",
69+
"nginx",
70+
"port",
71+
"ports",
72+
"proxy",
73+
"reverse",
5274
"tls",
53-
"encrypted",
5475
"tunnel",
5576
"vhost",
5677
"virtual",
57-
"virtuals",
58-
"ports",
59-
"domain",
60-
"domains"
78+
"virtuals"
6179
],
6280
"license": "MIT",
6381
"lint-staged": {
64-
"*.{js,jsx,mjs,ts,tsx,css,less,scss,json,graphql}": [
65-
"prettier --write --single-quote --trailing-comma none",
82+
"*.js": [
83+
"xo --fix",
6684
"git add"
6785
],
68-
"*.md": ["remark . -qfo", "git add"]
86+
"*.md": [
87+
"remark . -qfo",
88+
"git add"
89+
],
90+
"package.json": [
91+
"fixpack",
92+
"git add"
93+
]
6994
},
7095
"main": "index.js",
96+
"prettier": {
97+
"singleQuote": true,
98+
"bracketSpacing": true,
99+
"trailingComma": "none"
100+
},
101+
"publishConfig": {
102+
"access": "public"
103+
},
71104
"remarkConfig": {
72-
"plugins": ["preset-github"]
105+
"plugins": [
106+
"preset-github"
107+
]
73108
},
74109
"repository": {
75110
"type": "git",
@@ -83,31 +118,10 @@
83118
"test-coverage": "cross-env NODE_ENV=test nyc ava"
84119
},
85120
"xo": {
86-
"extends": "prettier",
87-
"plugins": ["prettier"],
88-
"parserOptions": {
89-
"sourceType": "script"
90-
},
91-
"rules": {
92-
"prettier/prettier": [
93-
"error",
94-
{
95-
"singleQuote": true,
96-
"bracketSpacing": true,
97-
"trailingComma": "none"
98-
}
99-
],
100-
"max-len": [
101-
"error",
102-
{
103-
"code": 80,
104-
"ignoreUrls": true
105-
}
106-
],
107-
"capitalized-comments": "off",
108-
"camelcase": "off",
109-
"no-warning-comments": "off"
110-
},
111-
"space": true
121+
"prettier": true,
122+
"space": true,
123+
"extends": [
124+
"xo-lass"
125+
]
112126
}
113127
}

test/test.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
11
const test = require('ava');
2+
const request = require('supertest');
23

3-
test.todo('write tests');
4+
const ProxyServer = require('..');
5+
6+
test('redirects http to https', async t => {
7+
const proxy = new ProxyServer();
8+
await proxy.listen();
9+
const res = await request(proxy.server).get('/foobar');
10+
const { port } = proxy.server.address();
11+
t.is(res.status, 301);
12+
t.is(res.headers.location, `https://127.0.0.1:${port}/foobar`);
13+
});
14+
15+
test('serves acme challenge', async t => {
16+
const config = {
17+
certbot: {
18+
name: 'name',
19+
contents: 'contents'
20+
}
21+
};
22+
const proxy = new ProxyServer(config);
23+
const res = await request(proxy.server).get(
24+
`/.well-known/acme-challenge/${config.certbot.name}`
25+
);
26+
t.is(res.status, 200);
27+
t.is(res.headers['content-type'], 'text/plain; charset=utf-8');
28+
t.is(res.text, config.certbot.contents);
29+
});

0 commit comments

Comments
 (0)