@rip-lang/server 1.3.9 → 1.3.11
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 +13 -12
- package/api.rip +1 -0
- package/certs/ripdev.io.crt +43 -0
- package/certs/ripdev.io.key +28 -0
- package/package.json +3 -2
- package/server.rip +22 -41
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ dependencies.
|
|
|
16
16
|
- **Multi-worker architecture** — Automatic worker spawning based on CPU cores
|
|
17
17
|
- **Hot module reloading** — Watches `*.rip` files by default, rolling restarts on change
|
|
18
18
|
- **Rolling restarts** — Zero-downtime deployments
|
|
19
|
-
- **Automatic HTTPS** —
|
|
19
|
+
- **Automatic HTTPS** — Shipped `*.ripdev.io` wildcard cert (green lock, zero setup)
|
|
20
20
|
- **mDNS discovery** — `.local` hostname advertisement
|
|
21
21
|
- **Request queue** — Built-in request buffering and load balancing
|
|
22
22
|
- **Built-in dashboard** — Server status UI at `rip.local`
|
|
@@ -846,9 +846,8 @@ rip serve [flags] [app-path]@<alias1>,<alias2>,...
|
|
|
846
846
|
| `https:<port>` | Set HTTPS port | 443, fallback 3443 |
|
|
847
847
|
| `w:<n>` | Worker count (`auto`, `half`, `2x`, `3x`, or number) | `half` of cores |
|
|
848
848
|
| `r:<reqs>,<secs>s` | Restart policy: requests, seconds (e.g., `5000,3600s`) | `10000,3600s` |
|
|
849
|
-
| `--cert=<path>` | TLS certificate path |
|
|
850
|
-
| `--key=<path>` | TLS private key path |
|
|
851
|
-
| `--auto-tls` | Try mkcert first, then self-signed | Self-signed only |
|
|
849
|
+
| `--cert=<path>` | TLS certificate path | Shipped `*.ripdev.io` cert |
|
|
850
|
+
| `--key=<path>` | TLS private key path | Shipped `*.ripdev.io` key |
|
|
852
851
|
| `--hsts` | Enable HSTS headers | Disabled |
|
|
853
852
|
| `--no-redirect-http` | Don't redirect HTTP to HTTPS | Redirects enabled |
|
|
854
853
|
| `--json-logging` | Output JSON access logs | Human-readable |
|
|
@@ -870,9 +869,6 @@ rip serve
|
|
|
870
869
|
# HTTP only
|
|
871
870
|
rip serve http
|
|
872
871
|
|
|
873
|
-
# HTTPS with mkcert
|
|
874
|
-
rip serve --auto-tls
|
|
875
|
-
|
|
876
872
|
# Production: 8 workers, no hot reload
|
|
877
873
|
rip serve --static w:8
|
|
878
874
|
|
|
@@ -966,17 +962,22 @@ The server provides these endpoints automatically:
|
|
|
966
962
|
|
|
967
963
|
## TLS Certificates
|
|
968
964
|
|
|
969
|
-
###
|
|
965
|
+
### Shipped Wildcard Cert (`*.ripdev.io`)
|
|
970
966
|
|
|
971
|
-
|
|
967
|
+
The server ships with a GlobalSign wildcard certificate for `*.ripdev.io`. Combined with DNS (`*.ripdev.io → 127.0.0.1`), every app gets trusted HTTPS automatically:
|
|
972
968
|
|
|
973
|
-
|
|
974
|
-
|
|
969
|
+
```bash
|
|
970
|
+
rip serve streamline # → https://streamline.ripdev.io (green lock)
|
|
971
|
+
rip serve analytics # → https://analytics.ripdev.io (green lock)
|
|
972
|
+
rip serve myapp # → https://myapp.ripdev.io (green lock)
|
|
973
|
+
```
|
|
975
974
|
|
|
976
|
-
|
|
975
|
+
No setup, no flags, no certificate generation. The app name becomes the subdomain.
|
|
977
976
|
|
|
978
977
|
### Custom Certificates
|
|
979
978
|
|
|
979
|
+
For production domains or custom setups, provide your own cert/key:
|
|
980
|
+
|
|
980
981
|
```bash
|
|
981
982
|
rip serve --cert=/path/to/cert.pem --key=/path/to/key.pem
|
|
982
983
|
```
|
package/api.rip
CHANGED
|
@@ -186,6 +186,7 @@ createContext = (req, params = {}) ->
|
|
|
186
186
|
else parseInt(duration) or 0
|
|
187
187
|
else 0
|
|
188
188
|
out.set 'Cache-Control', "public, max-age=#{seconds}, immutable"
|
|
189
|
+
out.set 'Expires', new Date(Date.now() + seconds * 1000).toUTCString()
|
|
189
190
|
return
|
|
190
191
|
|
|
191
192
|
session: {}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIGWzCCBUOgAwIBAgIMFMf54+s6EwpqpLa+MA0GCSqGSIb3DQEBCwUAMFUxCzAJ
|
|
3
|
+
BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSswKQYDVQQDEyJH
|
|
4
|
+
bG9iYWxTaWduIEdDQyBSNiBBbHBoYVNTTCBDQSAyMDI1MB4XDTI2MDIyNTEwMjQz
|
|
5
|
+
MloXDTI3MDMyOTEwMjQzMVowFjEUMBIGA1UEAwwLKi5yaXBkZXYuaW8wggEiMA0G
|
|
6
|
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBzo9MgygbFQH4mw5nj3wdt5HllRdk
|
|
7
|
+
mfbzxi02tJOMSZLgmeYiJ0VUZ9bcIbcif0gFv4na7+oYaKf0vLYsBArTzq6WYa7i
|
|
8
|
+
8Bzr/UYXlynzlZ3GS9qn5AGo1Y+jfHi239XE5xE4qCoybJU/NaFd0n5y/inMjUWx
|
|
9
|
+
G9yRC8foX0zW5tn3dYE8BR3o409sfvaf7gylvPDJGc8p86rCqEInsCbLQguiE5DV
|
|
10
|
+
L2eYia8q0yemuXUEKvdZ0KngyshuWdQkg9F6I68G7QXD/Pvm8sP6MiAx87aykQQb
|
|
11
|
+
1Fm9MQHhxOXyiSVKCR+lKJwcdBJF0hIBIwTeBA/9yQ8HfQl9FD6mXz8dAgMBAAGj
|
|
12
|
+
ggNoMIIDZDAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADCBmQYIKwYBBQUH
|
|
13
|
+
AQEEgYwwgYkwSQYIKwYBBQUHMAKGPWh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j
|
|
14
|
+
b20vY2FjZXJ0L2dzZ2NjcjZhbHBoYXNzbGNhMjAyNS5jcnQwPAYIKwYBBQUHMAGG
|
|
15
|
+
MGh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjZhbHBoYXNzbGNhMjAy
|
|
16
|
+
NTBXBgNVHSAEUDBOMAgGBmeBDAECATBCBgorBgEEAaAyCgEDMDQwMgYIKwYBBQUH
|
|
17
|
+
AgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMEQGA1Ud
|
|
18
|
+
HwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vZ3NnY2NyNmFs
|
|
19
|
+
cGhhc3NsY2EyMDI1LmNybDAhBgNVHREEGjAYggsqLnJpcGRldi5pb4IJcmlwZGV2
|
|
20
|
+
LmlvMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAWgBTF
|
|
21
|
+
tJOPbyvcHki/txAwhc7RsrtILTAdBgNVHQ4EFgQUOitYLYlCmzpOvCSqT8lWnyEk
|
|
22
|
+
CvMwggGFBgorBgEEAdZ5AgQCBIIBdQSCAXEBbwB9AI7KRwus3mrzogawpHqEt0b+
|
|
23
|
+
H8a/lT4l5ptO5AJI88boAAABnJRUaM0ACAAABQAC9hXVBAMARjBEAiBnEvFsYS+k
|
|
24
|
+
HcN7jHzpg6LHsrSb7aFHnrmsliLKxky4ygIgOJzdjwD9GcO79nbeajca4pxhrLyG
|
|
25
|
+
tjbuhmkQ3gD9COEAdwAcn2gs6frwRWlQ+BuWiofd2zIQ2EzmyLLjglJKxM9ZnwAA
|
|
26
|
+
AZyUVGgbAAAEAwBIMEYCIQC2o2qGrBvv5lPQl+CHYTFdjkiaobqUIC4nvmO9Hj0z
|
|
27
|
+
dgIhAP+96D5I8ryQ3HVslgWXAp1v8JAO8pdVQ+pX1e/j+dEfAHUATGPcmOWcHauI
|
|
28
|
+
9h6KPd6uj6tEozd7X5uUw/uhnPzBviYAAAGclFRm7gAABAMARjBEAiB0vpn6eh9X
|
|
29
|
+
fLVscIMPf+/iigYxxDO/9NkwG497CxM/bwIgWye6IgzH0RPlccR6C2idFtow2nUr
|
|
30
|
+
b7lWSNtHl04+9zAwDQYJKoZIhvcNAQELBQADggEBACSzZXZI5+1PH40ih224gjT3
|
|
31
|
+
8yElNS5rYREiAeJIgmZ8fQnxq0111AS+UWVAwQUFnnaM18E4Vz476J3vPpb+c4NB
|
|
32
|
+
91jHoM+axcvkd9bAlZswu1l1sZTqIbA3q9yCy2VD+tOtDHxZ1+b25ScLRn+IXpRl
|
|
33
|
+
h2h+NUPMllg5jyIhj7hYNd/SoyqyplA7NQ3/gWx1VFD90TfxzWO5/gbMh9QcC8aj
|
|
34
|
+
6ODQvfJovl6EOu6dnycRlm/MnChuM5+Iy+xXnaLiUTBGjnBOqAkuJ/ycOEGGNVyq
|
|
35
|
+
m3DYlp+Pky/a9COQA9Ig/TWFhWDfaOz+vFkvmVflQg9eFv1KsX0w47BbJhb0oos=
|
|
36
|
+
-----END CERTIFICATE-----
|
|
37
|
+
-----BEGIN CERTIFICATE-----
|
|
38
|
+
MIIFjTCCA3WgAwIBAgIRAIN9TriekS/nLK07x2kt3CAwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMjUwNTIxMDIzNjUyWhcNMjcwNTIxMDAwMDAwWjBVMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTErMCkGA1UEAxMiR2xvYmFsU2lnbiBHQ0MgUjYgQWxwaGFTU0wgQ0EgMjAyNTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/oiu0Bviq52UUEADbFWmgu3rC7KDSMoorLN1Wd03McG3Z1aP71DlPCE33838r72Dfuj5M9LXfiQLJpAu6MwNExmKOzothw4x0zGf5oBYyrCMGm3fBpLPafwYQ3MchBOWMTbf83rKUPLH48KCJ0MnU8GUl8oA/J81wIvbbKPuNrFf6hvJDccjzc4NyxLz3A89zjV2g5whCg5O0u9YX4Zxk9JHuc/LvllOJO4waAYLjbWBJkz3rV3ts1SmSYnJqmyRTIjXwQgRvhEYqtDbRskt0W7M6cPwCze3GTBN2UHNpHkMs3YmVxku68I0aOQn5+uz//fDROP3z1Z/7I
|
|
39
|
+
APteRtECAwEAAaOCAV8wggFbMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUxbSTj28r3B5Iv7cQMIXO0bK7SC0wHwYDVR0jBBgwFoAUrmwFo5MT4qLn4tcc1sfwf8hnU6AwewYIKwYBBQUHAQEEbzBtMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcDIuZ2xvYmFsc2lnbi5jb20vcm9vdHI2MDsGCCsGAQUFBzAChi9odHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9yb290LXI2LmNydDA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL3Jvb3QtcjYuY3JsMCEGA1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisGAQQBoDIKAQMwDQYJKoZIhvcNAQELBQADggIBAB/uvBuZf4CiuSahwiXn4geF52roAH+6jxsEPTXTfb7bbeMDXsYgRRsOTNA70ruZ
|
|
40
|
+
Tnz5DfFMuBhNoFhIFb0qR1izdy6VkdKOqFPNF2dOFI1EcnY9l2ory9mrzHqVbrL4vzUd17FLUVyjTVU7PAv4nxyhnO1GTeT83YlrdRF31NyR6bvZVTEERHmpbWSgeveJLRtaMzlGWiLZ8IwkH7o6GH3jp/KPtDW4Npu8w64HrRZdN2pqQhi7+YKwfHM7H+2U
|
|
41
|
+
dM1BGN0sjOWMVbMSB9MtCsleS2Mb7TRZEbOHxECJLLIluQypZr7Pol3+hAqrhyKIk+6y+Da0NeDuWxW59Ku4NvClqW1UFX1SpfNGhzVfp/CH+vPM1tySomx2jE0EnYZuGwVucXPBsp5nUWqUV9+143glVuS7GTg9hFPjNBInn17HbCoIIQIOzj5Vd9bK3A9U
|
|
42
|
+
GxXNpwenDHEalCsD/4eQYDHPhFE7sNe0D/OXu+FAM02VZkARx37Jp4bDdujvgL9PvZPR3wThvDN1CTU8Bc3xea3yKFAraKcPZLkhReQUAm2VpR+HSJRPlUpYizlF9WkLh3KcAVCBJWvnOkVwxyU5QJMcnwW95JlOtx+9100GL99jHE5rs3gXp7F4bg8H01QT9jVOhBBmQ7nQoXuwI0tqal2QUqZz3eeu62CU7xBwtfYR
|
|
43
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBzo9MgygbFQH4
|
|
3
|
+
mw5nj3wdt5HllRdkmfbzxi02tJOMSZLgmeYiJ0VUZ9bcIbcif0gFv4na7+oYaKf0
|
|
4
|
+
vLYsBArTzq6WYa7i8Bzr/UYXlynzlZ3GS9qn5AGo1Y+jfHi239XE5xE4qCoybJU/
|
|
5
|
+
NaFd0n5y/inMjUWxG9yRC8foX0zW5tn3dYE8BR3o409sfvaf7gylvPDJGc8p86rC
|
|
6
|
+
qEInsCbLQguiE5DVL2eYia8q0yemuXUEKvdZ0KngyshuWdQkg9F6I68G7QXD/Pvm
|
|
7
|
+
8sP6MiAx87aykQQb1Fm9MQHhxOXyiSVKCR+lKJwcdBJF0hIBIwTeBA/9yQ8HfQl9
|
|
8
|
+
FD6mXz8dAgMBAAECggEAGv6CmqFdDXKeYOp19eo4GyqFrYDX7oj8auVkSE2cDIr1
|
|
9
|
+
5IdDFOg74Z8KAATJLYqldTmBwccvZ8Fx/WZoiFZyzKAp1KPb+FuB58PSBrilHPqu
|
|
10
|
+
rF9F4CMjsQi39klAxhYEwCWAElBn+jiCDDkT1g3a03j/yPA3cA0FqoVFzaGyge8M
|
|
11
|
+
7vITBEyA0ZwJeFs0tQe+7t1r6hbf9+3w2Z3v+hQfAglIStjS5hXqXY+qlHKVg/cH
|
|
12
|
+
qt2dnQFjwUCs2JpPkT7aZJdAaOfDv2A6B1tXlEjvIXbjRHNy+gnuUAxN8KB8XxGF
|
|
13
|
+
iBgTkowuLSo5VzmV8E24UC916rI/2ZsS3ShztLmuGQKBgQDsDqS5yqm/zbioWX1O
|
|
14
|
+
kx95CNi9x9YOCLrV/fui8NIsKWueVEHXlgcaDO6HNyNEVHvuIrqtUWYh62C7Eyad
|
|
15
|
+
YtBRyITZvtyS1T4JPCd0eblu2XDFTccKyLccPW8VaeNMzV8GNYHx0MmPH1wLw7nu
|
|
16
|
+
FCQ47FUAA9Qr6bWLZaImmzl+5QKBgQDSLiRf60DKtqar6js815YTCdCCzl6HUFqV
|
|
17
|
+
DIDFcF7Hher5fxAKD3OQAVLBIu5S4dJLOajew94W5FukMcfN9Wk332ZH4AxWCuHv
|
|
18
|
+
vbws14d3vNAvlKCYiQ3R2052rM3KqCE4rMJc6AQ/2GEE1XzS2CWEKLbOkk4qoKxs
|
|
19
|
+
U2HxpS4D2QKBgA9pmVnEILc0QGVFiofx1TE64aPqg1BhQ4mrTp3B6YcWoT8yMyZX
|
|
20
|
+
VlleFMjhUb0pYvoWbGfak7eNPcCZLIFELWPZmsr4ykAQCj/iHJVfSTsymUlYnbFX
|
|
21
|
+
j5UZccJNKpkeI6EtJzHZtv9QRdtCyUYBLKhGzfn1Rgoj9UWHukGZCvT9AoGAVsx5
|
|
22
|
+
dydXbZ/6uvqTli/OKXSfKLYDMcyMbAtqzp72dV2nyXug6xaweeMiAuLjG1VpHGnm
|
|
23
|
+
hIDNIhUSh3+LbVIRLuLSgZJUZeA+qFxp7vbfWiKes1ek7vmCvIzeHYKFxlCiz54A
|
|
24
|
+
8o9a2ecJQg7MauKas7aAsFSZdV8/dckFpN67XxkCgYEApSsiCH3/FSKpmriCEBcI
|
|
25
|
+
aqz132RvkQ9622kkMnLo3TOIbjGmW3tnTGpCeCP5iCsknkJMoyA6CF/8lJcvBBVp
|
|
26
|
+
S/sFuOblz6i1+11yfir3znkWfotA0c4ClHtp0ebcjjbf2Y2f+T9XVHsVYoIevirk
|
|
27
|
+
5IxlgMVXTb4IG5lOEdl8TRA=
|
|
28
|
+
-----END PRIVATE KEY-----
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rip-lang/server",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.11",
|
|
4
4
|
"description": "Pure Rip web framework and application server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "api.rip",
|
|
@@ -45,13 +45,14 @@
|
|
|
45
45
|
"author": "Steve Shreeve <steve.shreeve@gmail.com>",
|
|
46
46
|
"license": "MIT",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"rip-lang": ">=3.13.
|
|
48
|
+
"rip-lang": ">=3.13.18"
|
|
49
49
|
},
|
|
50
50
|
"files": [
|
|
51
51
|
"api.rip",
|
|
52
52
|
"middleware.rip",
|
|
53
53
|
"server.rip",
|
|
54
54
|
"server.html",
|
|
55
|
+
"certs/",
|
|
55
56
|
"bin/",
|
|
56
57
|
"tests/",
|
|
57
58
|
"docs/",
|
package/server.rip
CHANGED
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
# bun server.rip list # List registered hosts
|
|
13
13
|
# ==============================================================================
|
|
14
14
|
|
|
15
|
-
import { existsSync, statSync, readFileSync, writeFileSync, unlinkSync,
|
|
15
|
+
import { existsSync, statSync, readFileSync, writeFileSync, unlinkSync, watch, utimesSync } from 'node:fs'
|
|
16
16
|
import { basename, dirname, isAbsolute, join, resolve } from 'node:path'
|
|
17
|
-
import {
|
|
17
|
+
import { cpus, networkInterfaces } from 'node:os'
|
|
18
18
|
import { X509Certificate } from 'node:crypto'
|
|
19
19
|
|
|
20
20
|
# Match capture holder for Rip's =~
|
|
@@ -33,6 +33,7 @@ SHUTDOWN_TIMEOUT_MS = 30000 # Max time to wait for in-flight requests on shutd
|
|
|
33
33
|
# ==============================================================================
|
|
34
34
|
|
|
35
35
|
nowMs = -> Date.now()
|
|
36
|
+
formatPort = (protocol, port) -> if (protocol is 'https' and port is 443) or (protocol is 'http' and port is 80) then '' else ":#{port}"
|
|
36
37
|
|
|
37
38
|
getWorkerSocketPath = (prefix, id) -> "/tmp/#{prefix}.#{id}.sock"
|
|
38
39
|
getControlSocketPath = (prefix) -> "/tmp/#{prefix}.ctl.sock"
|
|
@@ -330,7 +331,6 @@ parseFlags = (argv) ->
|
|
|
330
331
|
httpsPort
|
|
331
332
|
certPath: getKV('--cert=')
|
|
332
333
|
keyPath: getKV('--key=')
|
|
333
|
-
autoTls: has('--auto-tls')
|
|
334
334
|
hsts: has('--hsts')
|
|
335
335
|
redirectHttp: not has('--no-redirect-http')
|
|
336
336
|
reload
|
|
@@ -739,6 +739,7 @@ class Server
|
|
|
739
739
|
for alias in @flags.appAliases
|
|
740
740
|
host = if alias.includes('.') then alias else "#{alias}.local"
|
|
741
741
|
@hostRegistry.add(host)
|
|
742
|
+
@hostRegistry.add("#{@flags.appName}.ripdev.io")
|
|
742
743
|
|
|
743
744
|
start: ->
|
|
744
745
|
httpOnly = @flags.httpsPort is null
|
|
@@ -1009,6 +1010,10 @@ class Server
|
|
|
1009
1010
|
host = if alias.includes('.') then alias else "#{alias}.local"
|
|
1010
1011
|
@startMdnsAdvertisement(host)
|
|
1011
1012
|
|
|
1013
|
+
port = @flags.httpsPort or @flags.httpPort or 80
|
|
1014
|
+
protocol = if @flags.httpsPort then 'https' else 'http'
|
|
1015
|
+
console.log "rip-server: #{protocol}://#{@flags.appName}.ripdev.io#{formatPort(protocol, port)}"
|
|
1016
|
+
|
|
1012
1017
|
controlFetch: (req) ->
|
|
1013
1018
|
url = new URL(req.url)
|
|
1014
1019
|
|
|
@@ -1065,42 +1070,18 @@ class Server
|
|
|
1065
1070
|
console.error 'Failed to read TLS cert/key from provided paths. Use http or fix paths.'
|
|
1066
1071
|
process.exit(2)
|
|
1067
1072
|
|
|
1068
|
-
#
|
|
1069
|
-
certsDir = join(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
# Try mkcert first (trusted local CA)
|
|
1073
|
-
if @flags.autoTls
|
|
1074
|
-
certPath = join(certsDir, 'localhost.pem')
|
|
1075
|
-
keyPath = join(certsDir, 'localhost-key.pem')
|
|
1076
|
-
unless existsSync(certPath) and existsSync(keyPath)
|
|
1077
|
-
try
|
|
1078
|
-
Bun.spawnSync(['mkcert', '-install'])
|
|
1079
|
-
Bun.spawnSync(['mkcert', '-key-file', keyPath, '-cert-file', certPath, 'localhost', '127.0.0.1', '::1'])
|
|
1080
|
-
catch
|
|
1081
|
-
null # fall through to self-signed
|
|
1082
|
-
if existsSync(certPath) and existsSync(keyPath)
|
|
1083
|
-
cert = readFileSync(certPath, 'utf8')
|
|
1084
|
-
key = readFileSync(keyPath, 'utf8')
|
|
1085
|
-
@printCertSummary(cert)
|
|
1086
|
-
return { cert, key }
|
|
1087
|
-
|
|
1088
|
-
# Self-signed via openssl
|
|
1089
|
-
certPath = join(certsDir, 'selfsigned-localhost.pem')
|
|
1090
|
-
keyPath = join(certsDir, 'selfsigned-localhost-key.pem')
|
|
1091
|
-
unless existsSync(certPath) and existsSync(keyPath)
|
|
1092
|
-
try
|
|
1093
|
-
Bun.spawnSync(['openssl', 'req', '-x509', '-nodes', '-newkey', 'rsa:2048', '-keyout', keyPath, '-out', certPath, '-subj', '/CN=localhost', '-days', '3650'])
|
|
1094
|
-
catch
|
|
1095
|
-
console.error 'TLS required but could not provision a certificate (mkcert/openssl missing). Use http or provide --cert/--key.'
|
|
1096
|
-
process.exit(2)
|
|
1073
|
+
# Shipped wildcard cert for *.ripdev.io (GlobalSign, valid for all subdomains)
|
|
1074
|
+
certsDir = join(import.meta.dir, 'certs')
|
|
1075
|
+
certPath = join(certsDir, 'ripdev.io.crt')
|
|
1076
|
+
keyPath = join(certsDir, 'ripdev.io.key')
|
|
1097
1077
|
try
|
|
1098
1078
|
cert = readFileSync(certPath, 'utf8')
|
|
1099
1079
|
key = readFileSync(keyPath, 'utf8')
|
|
1100
1080
|
@printCertSummary(cert)
|
|
1101
1081
|
return { cert, key }
|
|
1102
|
-
catch
|
|
1103
|
-
console.error
|
|
1082
|
+
catch e
|
|
1083
|
+
console.error "rip-server: failed to load TLS certs from #{certsDir}: #{e.message}"
|
|
1084
|
+
console.error 'Use --cert/--key to provide your own, or use http to disable TLS.'
|
|
1104
1085
|
process.exit(2)
|
|
1105
1086
|
|
|
1106
1087
|
printCertSummary: (certPem) ->
|
|
@@ -1153,7 +1134,7 @@ class Server
|
|
|
1153
1134
|
stderr: 'ignore'
|
|
1154
1135
|
|
|
1155
1136
|
@mdnsProcesses.set(host, proc)
|
|
1156
|
-
console.log "rip-server: #{protocol}://#{host}
|
|
1137
|
+
console.log "rip-server: #{protocol}://#{host}#{formatPort(protocol, port)}"
|
|
1157
1138
|
catch e
|
|
1158
1139
|
console.error "rip-server: failed to advertise #{host} via mDNS:", e.message
|
|
1159
1140
|
|
|
@@ -1191,11 +1172,10 @@ main = ->
|
|
|
1191
1172
|
|
|
1192
1173
|
Network:
|
|
1193
1174
|
http HTTP only (no TLS)
|
|
1194
|
-
https HTTPS with
|
|
1175
|
+
https HTTPS with trusted *.ripdev.io cert (default)
|
|
1195
1176
|
<port> Listen on specific port
|
|
1196
|
-
--cert=<path> TLS certificate file
|
|
1197
|
-
--key=<path> TLS key file
|
|
1198
|
-
--auto-tls Generate TLS cert via mkcert
|
|
1177
|
+
--cert=<path> TLS certificate file (overrides shipped cert)
|
|
1178
|
+
--key=<path> TLS key file (overrides shipped cert)
|
|
1199
1179
|
--hsts Enable HSTS header
|
|
1200
1180
|
--no-redirect-http Don't redirect HTTP to HTTPS
|
|
1201
1181
|
|
|
@@ -1301,8 +1281,9 @@ main = ->
|
|
|
1301
1281
|
mgr.start!
|
|
1302
1282
|
|
|
1303
1283
|
httpOnly = flags.httpsPort is null
|
|
1304
|
-
|
|
1305
|
-
|
|
1284
|
+
protocol = if httpOnly then 'http' else 'https'
|
|
1285
|
+
port = flags.httpsPort or flags.httpPort or 80
|
|
1286
|
+
console.log "rip-server: app=#{flags.appName} workers=#{flags.workers} url=#{protocol}://#{flags.appName}.ripdev.io#{formatPort(protocol, port)}/server"
|
|
1306
1287
|
|
|
1307
1288
|
# ==============================================================================
|
|
1308
1289
|
# Entry Point
|