Skip to content

Commit

Permalink
feat: refactored and improved API, better certbot support
Browse files Browse the repository at this point in the history
  • Loading branch information
niftylettuce committed Sep 13, 2019
1 parent a3bb218 commit 271818d
Show file tree
Hide file tree
Showing 5 changed files with 5,374 additions and 3,201 deletions.
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@ yarn add @ladjs/proxy

## Usage

```js
#!/usr/bin/env node
const proxy = require('@ladjs/proxy');

proxy.listen('127.0.0.1', 80);
```
See <https://github.com/ladjs/lad/blob/master/template/proxy.js> for the most up to date usage example.


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


##
##

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

Expand Down
66 changes: 57 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,62 @@
const http = require('http');
const url = require('url');
const util = require('util');

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

res.end();
});
class ProxyServer {
constructor(config) {
this.config = {
logger: console,
port: process.env.PROXY_PORT || null,
certbot: {
name: process.env.CERTBOT_WELL_KNOWN_NAME || null,
contents: process.env.CERTBOT_WELL_KNOWN_CONTENTS || null
},
...config
};

if (!module.parent) proxy.listen(80);
const router = new Router();

module.exports = proxy;
// support for lets encrypt verification
if (
_.isObject(this.config.certbot) &&
_.isString(this.config.certbot.name) &&
_.isString(this.config.certbot.contents)
)
router.get(
`/.well-known/acme-challenge/${this.config.certbot.name}`,
(req, res) => {
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end(this.config.certbot.contents);
}
);

router.use((req, res) => {
res.writeHead(301, {
Location: parse(`https://${req.headers.host}${req.url}`).href
});
res.end();
});

this.server = http.createServer((req, res) => {
router(req, res, finalhandler(req, res));
});

// bind listen/close to this
this.listen = this.listen.bind(this);
this.close = this.close.bind(this);
}

async listen(port) {
await util.promisify(this.server.listen).bind(this.server)(port);
}

async close() {
await util.promisify(this.server.close).bind(this.server);
}
}

module.exports = ProxyServer;
140 changes: 77 additions & 63 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,108 @@
"description": "Proxy for Lad",
"version": "0.0.1",
"author": "Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)",
"ava": {
"failFast": true,
"verbose": true
},
"bugs": {
"url": "https://github.com/ladjs/proxy/issues",
"email": "niftylettuce@gmail.com"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"contributors": [
"Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)"
],
"dependencies": {},
"ava": {
"failFast": true,
"verbose": true
"dependencies": {
"finalhandler": "^1.1.2",
"lodash": "^4.17.15",
"router": "^1.3.3",
"url-parse": "^1.4.7"
},
"devDependencies": {
"ava": "^0.22.0",
"codecov": "^2.3.0",
"cross-env": "^5.0.5",
"eslint": "^4.5.0",
"eslint-config-prettier": "^2.3.0",
"eslint-plugin-prettier": "^2.2.0",
"husky": "^0.14.3",
"lint-staged": "^4.0.4",
"nyc": "^11.1.0",
"prettier": "^1.6.1",
"remark-cli": "^4.0.0",
"remark-preset-github": "^0.0.6",
"xo": "^0.19.0"
"@commitlint/cli": "^8.1.0",
"@commitlint/config-conventional": "^8.1.0",
"ava": "^2.3.0",
"codecov": "^3.5.0",
"cross-env": "^5.2.1",
"eslint": "^6.3.0",
"eslint-config-xo-lass": "^1.0.3",
"fixpack": "^2.3.1",
"husky": "^3.0.5",
"lint-staged": "^9.2.5",
"nyc": "^14.1.1",
"remark-cli": "^7.0.0",
"remark-preset-github": "^0.0.16",
"supertest": "^4.0.2",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8.3"
},
"homepage": "https://github.com/ladjs/proxy",
"husky": {
"hooks": {
"pre-commit": "lint-staged && npm test",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"keywords": [
"proxy",
"lad",
"koa",
"http",
"handler",
"nginx",
"reverse",
"https",
"hosts",
"host",
"config",
"domain",
"domains",
"encrypted",
"forward",
"port",
"forwarding",
"handler",
"host",
"hosts",
"http",
"https",
"koa",
"lad",
"nginx",
"port",
"ports",
"proxy",
"reverse",
"tls",
"encrypted",
"tunnel",
"vhost",
"virtual",
"virtuals",
"ports",
"domain",
"domains"
"virtuals"
],
"license": "MIT",
"lint-staged": {
"*.{js,jsx,mjs,ts,tsx,css,less,scss,json,graphql}": [
"prettier --write --single-quote --trailing-comma none",
"*.js": [
"xo --fix",
"git add"
],
"*.md": ["remark . -qfo", "git add"]
"*.md": [
"remark . -qfo",
"git add"
],
"package.json": [
"fixpack",
"git add"
]
},
"main": "index.js",
"prettier": {
"singleQuote": true,
"bracketSpacing": true,
"trailingComma": "none"
},
"publishConfig": {
"access": "public"
},
"remarkConfig": {
"plugins": ["preset-github"]
"plugins": [
"preset-github"
]
},
"repository": {
"type": "git",
Expand All @@ -83,31 +118,10 @@
"test-coverage": "cross-env NODE_ENV=test nyc ava"
},
"xo": {
"extends": "prettier",
"plugins": ["prettier"],
"parserOptions": {
"sourceType": "script"
},
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"bracketSpacing": true,
"trailingComma": "none"
}
],
"max-len": [
"error",
{
"code": 80,
"ignoreUrls": true
}
],
"capitalized-comments": "off",
"camelcase": "off",
"no-warning-comments": "off"
},
"space": true
"prettier": true,
"space": true,
"extends": [
"xo-lass"
]
}
}
28 changes: 27 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
const test = require('ava');
const request = require('supertest');

test.todo('write tests');
const ProxyServer = require('..');

test('redirects http to https', async t => {
const proxy = new ProxyServer();
await proxy.listen();
const res = await request(proxy.server).get('/foobar');
const { port } = proxy.server.address();
t.is(res.status, 301);
t.is(res.headers.location, `https://127.0.0.1:${port}/foobar`);
});

test('serves acme challenge', async t => {
const config = {
certbot: {
name: 'name',
contents: 'contents'
}
};
const proxy = new ProxyServer(config);
const res = await request(proxy.server).get(
`/.well-known/acme-challenge/${config.certbot.name}`
);
t.is(res.status, 200);
t.is(res.headers['content-type'], 'text/plain; charset=utf-8');
t.is(res.text, config.certbot.contents);
});
Loading

0 comments on commit 271818d

Please sign in to comment.