Skip to content

Commit 186b5ba

Browse files
authored
Merge pull request #13 from daquinoaldo/develop-4.1.0
Develop 4.1.0
2 parents 49792e1 + 3dc0988 commit 186b5ba

File tree

10 files changed

+2026
-1497
lines changed

10 files changed

+2026
-1497
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# Pull Request Details
77

88
## Related Issue
9-
Please, open a issue before a pull request. It will help in understanding better the PR aim.
9+
Please, open an issue before a pull request. It will help in understanding better the PR aim.
1010

1111
## Types of changes
1212
<!-- Put an `x` in all the boxes that apply -->
@@ -19,8 +19,7 @@ Please, open a issue before a pull request. It will help in understanding better
1919
<!-- Go over all the following points, and put an `x` in all the boxes that apply. -->
2020
<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
2121
- [ ] My code follows the code style of this project.
22-
- [ ] My change requires a change to the documentation.
23-
- [ ] I have updated the documentation accordingly.
22+
- [ ] I have updated the documentation or my changes dont require it.
2423
- [ ] I have read the [CONTRIBUTING](CONTRIBUTING.md) document.
25-
- [ ] I have added tests to cover my changes (or the exist one were enough).
24+
- [ ] I have added tests to cover my changes (or the existing one were enough).
2625
- [ ] All new and existing tests passed.

.gitignore

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
# MacOS
22
.DS_STORE
33

4-
# IDEs
5-
.idea
6-
*.iml
7-
8-
# Node & npm
4+
# Node, npm & CI
95
node_modules
106
coverage
117
.nyc_output
128

13-
# Certificates
14-
cert/localhost.*
15-
cert/mkcert-*
9+
# Build
10+
build

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ language: node_js
66
node_js:
77
- node
88
- 10
9-
- 7.6
9+
- 8
1010
after_success: npm run coveralls

README.md

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,32 @@ It works with MacOS, Linux and Windows, on Chrome and Firefox, and requires you
1212
[![Known Vulnerabilities](https://snyk.io/test/npm/https-localhost/badge.svg)](https://snyk.io/test/npm/https-localhost)
1313
[![GitHub issues](https://img.shields.io/github/issues/daquinoaldo/https-localhost.svg)](https://github.com/daquinoaldo/https-localhost/issues)
1414

15+
1516
## Install and use standalone
1617
```
17-
npm i -g https-localhost
18+
npm i -g --only=prod https-localhost
1819
```
1920
```
2021
serve ~/myproj
2122
```
2223
- `sudo` may be necessary.
2324
- If a static path is not provided the current directory content will be served.
24-
- You can change the port setting the PORT environmental variable: `PORT=4433 serve ~/myproj`.
25+
- You can change the **port** setting the `PORT` environmental variable: `PORT=4433 serve ~/myproj`. Specifying port number will also prevent http to https redirect.
26+
27+
### Binaries
28+
If you don't have Node.js installed just use a packaged version! Download it from the [release page](https://github.com/daquinoaldo/https-localhost/releases).
29+
```
30+
// Linux
31+
./https-localhost-linux ~/myproj
32+
33+
// MacOS
34+
./https-localhost-macos ~/myproj
35+
36+
// Windows
37+
./https-localhost-win.exe C:\User\me\myproj
38+
```
39+
**Tip 1:** on Windows just drag the folder on the executable to serve itV.
40+
**Tip 2:** on all platform put the executable on the folder you want to serve and double-click it.
2541

2642

2743
## Use as module
@@ -36,9 +52,13 @@ const app = httpLocalhost()
3652
// app is an express app, do what you usually do with express
3753
app.listen(port)
3854
```
39-
- If the port number is not provided, it will listen on 443.
40-
- To redirect the http traffic to https use `app.redirect()`.
41-
- You can serve static files with `app.serve(path)`.
55+
- If the **port** number is not provided, it will listen on 443.
56+
- To **redirect** the http traffic to https use `app.redirect()`.
57+
- You can serve **static files** with `app.serve(path)`.
58+
59+
**Tip:** consider installing it as a dev dependency: this is not a production tool!
60+
`npm i --save-dev https-localhost`
61+
4262

4363
## Production
4464
This tool has a production version that activates **HTTP/2**, **compression** and **minify**.
@@ -49,6 +69,7 @@ I decide to not activate it by default since it is usually an unwanted behaviour
4969

5070
**IMPORTANT**: the fact that there is a production enviornment doesn't mean that this tool is suitable for production. It's intended to be used only for local testing.
5171

72+
5273
## Why and how it works
5374
Serving static content on localhost in a trusted SSL connection is not so simple.
5475
It requires to manually generate and trust certificates, with complicate commands and many manual steps.
@@ -76,9 +97,19 @@ Checkout the updated list [here](https://github.com/FiloSottile/mkcert/blob/mast
7697

7798
## Troubleshooting
7899
### Node.js version
79-
https-localhost requires Node.js 7.6 or higher.
100+
https-localhost requires Node.js 8 or higher.
80101
<sub>If you need compatibility with previously Node.js versions let me know, I'll try to rearrange the code.</sub>
81102

103+
### root required
104+
- **At first run** this tool generate a trusted certificate. The sudo password may be required. If you cannot provide the sudo password generate a `localhost.key` and `localhost.crt` and specify its path with `CERT_PATH=/diractory/containing/certificates/ serve ~/myproj`.
105+
- **At each run** the password may be required to run the server on port 443 and 80. To avoid the script ask for password specify a different port number: `PORT=4433 serve ~/myproj`.
106+
107+
### EACCES
108+
Run with sudo to use the default ports 443 and 80. You can also change port with: `PORT=4433 serve ~/myproj`.
109+
110+
### EADDRINUSE
111+
Another service on your machine is using port 443 or port 80. Stop it or change port with `PORT=4433 serve ~/myproj`.
112+
82113
### RangeError
83114
```
84115
RangeError: Invalid typed array length: -4095
@@ -89,6 +120,12 @@ It should be present only with `NODE_ENV=production`, hence the easiest fix is t
89120

90121
I've tried to reproduce this error without any success (checkout the [Travis build logs](https://travis-ci.org/daquinoaldo/https-localhost)). If you can help please open an issue and describe as better as you can how to reproduce it, I'll be happy to help you.
91122

123+
124+
## Contributing
125+
Each contribute is welcome!
126+
Please, checkout the [contributing guidelines](.github/CONTRIBUTING.md).
127+
128+
92129
## License
93130
Is released under [AGPL-3.0 - GNU Affero General Public License v3.0](LICENSE).
94131

cert/generate.js

Lines changed: 0 additions & 85 deletions
This file was deleted.

certs.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env node
2+
3+
const path = require("path")
4+
const fs = require("fs")
5+
const exec = require("child_process").exec
6+
const https = require("https")
7+
const getAppDataPath = require("appdata-path")
8+
9+
const MKCERT_VERSION = "v1.3.0"
10+
const CERT_PATH = getAppDataPath("https-localhost")
11+
12+
// get the executable name
13+
function getExe() {
14+
/* istanbul ignore next: tested on all platform on travis */
15+
switch (process.platform) {
16+
case "darwin":
17+
return "mkcert-" + MKCERT_VERSION + "-darwin-amd64"
18+
case "linux":
19+
return "mkcert-" + MKCERT_VERSION + "-linux-amd64"
20+
case "win32":
21+
return "mkcert-" + MKCERT_VERSION + "-windows-amd64.exe"
22+
default:
23+
console.warn("Cannot generate the localhost certificate on your " +
24+
"platform. Please, consider contacting the developer if you can help.")
25+
process.exit(0)
26+
}
27+
}
28+
29+
// download a binary file
30+
function download(url, path) {
31+
console.log("Downloading the mkcert executable...")
32+
const file = fs.createWriteStream(path)
33+
return new Promise(resolve => {
34+
function get(url, file) {
35+
https.get(url, (response) => {
36+
if (response.statusCode === 302) get(response.headers.location, file)
37+
else response.pipe(file).on("finish", resolve)
38+
})
39+
}
40+
get(url, file)
41+
})
42+
}
43+
44+
// execute the binary executable to generate the certificates
45+
function mkcert(appDataPath, exe) {
46+
const logPath = path.join(appDataPath, "mkcert.log")
47+
const errPath = path.join(appDataPath, "mkcert.err")
48+
// escape spaces in appDataPath (Mac OS)
49+
appDataPath = appDataPath.replace(" ", "\\ ")
50+
const exePath = path.join(appDataPath, exe)
51+
const crtPath = path.join(appDataPath, "localhost.crt")
52+
const keyPath = path.join(appDataPath, "localhost.key")
53+
const cmd = exePath + " -install -cert-file " + crtPath +
54+
" -key-file " + keyPath + " localhost"
55+
return new Promise((resolve, reject) => {
56+
console.log("Running mkcert to generate certificates...")
57+
exec(cmd, (err, stdout, stderr) => {
58+
// log
59+
const errFun = err => {
60+
/* istanbul ignore if: cannot be tested */
61+
if (err) console.error(err)
62+
}
63+
fs.writeFile(logPath, stdout, errFun)
64+
fs.writeFile(errPath, stderr, errFun)
65+
/* istanbul ignore if: cannot be tested */
66+
if (err) reject(err)
67+
resolve()
68+
})
69+
})
70+
}
71+
72+
async function generate(appDataPath = CERT_PATH) {
73+
console.info("Generating certificates...")
74+
// mkdir if not exists
75+
/* istanbul ignore else: not relevant */
76+
if (!fs.existsSync(appDataPath))
77+
fs.mkdirSync(appDataPath)
78+
// build the executable url and path
79+
const url = "https://github.com/FiloSottile/mkcert/releases/download/" +
80+
MKCERT_VERSION + "/"
81+
const exe = getExe()
82+
const exePath = path.join(appDataPath, exe)
83+
// download the executable
84+
await download(url + exe, exePath)
85+
// make binary executable
86+
fs.chmodSync(exePath, "0755")
87+
// execute the binary
88+
await mkcert(appDataPath, exe)
89+
console.log("Certificates generated, installed and trusted. Ready to go!")
90+
}
91+
92+
async function getCerts() {
93+
const certPath = process.env.CERT_PATH || CERT_PATH
94+
try {
95+
return {
96+
key: fs.readFileSync(path.join(certPath, "localhost.key")),
97+
cert: fs.readFileSync(path.join(certPath, "localhost.crt"))
98+
}
99+
} catch (e) {
100+
if (certPath !== CERT_PATH) {
101+
console.error("Cannot find localhost.key and localhost.crt in the" +
102+
" specified path: " + certPath)
103+
process.exit(1)
104+
} else {
105+
// Missing certificates (first run)
106+
// generate the certificate
107+
await generate(CERT_PATH)
108+
// recursive call
109+
return getCerts()
110+
}
111+
}
112+
}
113+
114+
// delete a folder and the file inside it
115+
function remove(appDataPath = CERT_PATH) {
116+
if (fs.existsSync(appDataPath)) {
117+
fs.readdirSync(appDataPath)
118+
.forEach(file => fs.unlinkSync(path.join(appDataPath, file)))
119+
fs.rmdirSync(appDataPath)
120+
}
121+
}
122+
123+
// run as script
124+
/* istanbul ignore if: cannot be tested */
125+
if (require.main === module)
126+
// if run with -u or --uninstall
127+
if (process.argv.length === 3 &&
128+
(process.argv[2] === "-u" || process.argv[2] === "--uninstall")) {
129+
remove()
130+
console.info("Certificates removed.")
131+
} else try { // install
132+
generate()
133+
} catch (err) { console.error("\nExec error: " + err) }
134+
135+
// export as module
136+
module.exports = {
137+
getCerts,
138+
generate,
139+
remove
140+
}

0 commit comments

Comments
 (0)