fbi-proxy 1.1.0 → 1.3.0
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/Caddyfile +30 -2
- package/README.md +121 -94
- package/package.json +47 -12
- package/{release-flat/proxy-linux-arm64 → release/fbi-proxy-linux-arm64} +0 -0
- package/{release-flat/proxy-linux-x64 → release/fbi-proxy-linux-x64} +0 -0
- package/release/{proxy-macos-arm64/proxy-macos-arm64 → fbi-proxy-macos-arm64} +0 -0
- package/release/{proxy-macos-x64/proxy-macos-x64 → fbi-proxy-macos-x64} +0 -0
- package/{release-flat/proxy-windows-arm64.exe → release/fbi-proxy-windows-arm64.exe} +0 -0
- package/{release-flat/proxy-windows-x64.exe → release/fbi-proxy-windows-x64.exe} +0 -0
- package/ts/buildFbiProxy.ts +33 -0
- package/ts/cli.ts +71 -91
- package/ts/dRun.ts +112 -0
- package/ts/download-fbiproxy.ts +35 -0
- package/ts/getProxyFilename.ts +11 -0
- package/.gitattributes +0 -31
- package/.github/workflows/release.yml +0 -114
- package/.releaserc.json +0 -37
- package/CHANGELOG.md +0 -24
- package/Dockerfile +0 -38
- package/INSTALL.md +0 -161
- package/PINGORA_PROXY.md +0 -127
- package/RUST_PROXY.md +0 -85
- package/build-proxy.bat +0 -15
- package/build-proxy.sh +0 -15
- package/bun.lock +0 -1238
- package/docker-compose.yml +0 -9
- package/release/proxy-linux-arm64/proxy-linux-arm64 +0 -0
- package/release/proxy-linux-x64/proxy-linux-x64 +0 -0
- package/release/proxy-windows-arm64.exe/proxy-windows-arm64.exe +0 -0
- package/release/proxy-windows-x64.exe/proxy-windows-x64.exe +0 -0
- package/release-flat/proxy-macos-arm64 +0 -0
- package/release-flat/proxy-macos-x64 +0 -0
- package/rs/.cargo/config.toml +0 -5
- package/rs/Cargo.lock +0 -1220
- package/rs/Cargo.toml +0 -19
- package/rs/build-windows.bat +0 -60
- package/rs/proxy.rs +0 -248
- package/tsconfig.json +0 -22
package/Caddyfile
CHANGED
|
@@ -7,13 +7,41 @@
|
|
|
7
7
|
# on_demand_tls {
|
|
8
8
|
# ask http://localhost:{$PROX}/CHECK_TLS
|
|
9
9
|
# }
|
|
10
|
+
servers {
|
|
11
|
+
trusted_proxies static private_ranges
|
|
12
|
+
trusted_proxies_strict
|
|
13
|
+
}
|
|
14
|
+
# auto_https disable_redirects
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
# unwrap all https
|
|
13
|
-
|
|
18
|
+
http://*, http://*.*, http://*.*.*, http://*.*.*.*, https://*, https://*.*, https://*.*.*, https://*.*.*.* {
|
|
14
19
|
tls internal {
|
|
15
20
|
on_demand
|
|
16
21
|
}
|
|
22
|
+
# match **.fbi.com use regex match against to host
|
|
23
|
+
@subhost {
|
|
24
|
+
header_regexp subhost Host ^((?:(.+)\.)?{$FBIHOST:fbi.com})$
|
|
25
|
+
}
|
|
26
|
+
@fullhost {
|
|
27
|
+
header_regexp fullhost Host ^(.+)$
|
|
28
|
+
}
|
|
29
|
+
# debug
|
|
30
|
+
# handle @subhost {
|
|
31
|
+
# respond "https://{re.subhost.1}{uri} => http://{re.subhost.2}{uri}"
|
|
32
|
+
# }
|
|
33
|
+
|
|
34
|
+
reverse_proxy @subhost :{$FBIPROXY_PORT:24306} {
|
|
35
|
+
# strip the fbi.com part from the host
|
|
36
|
+
header_up Host {re.subhost.2}
|
|
37
|
+
# header_up X-Forwarded-Host {re.subhost.1}
|
|
38
|
+
}
|
|
39
|
+
reverse_proxy @fullhost :{$FBIPROXY_PORT:24306} {
|
|
40
|
+
header_up Host {re.fullhost.1}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# 3000.amd.fbi.com => *.amd.fbi.com goes to amd.fbi.com with 3000.localhost host
|
|
17
44
|
|
|
18
|
-
|
|
45
|
+
# for all other hosts, 404
|
|
46
|
+
# respond 404
|
|
19
47
|
}
|
package/README.md
CHANGED
|
@@ -1,158 +1,185 @@
|
|
|
1
1
|
# fbi-proxy
|
|
2
2
|
|
|
3
|
-
FBI Proxy is a super easy way to turn your local network over
|
|
3
|
+
FBI Proxy is a super easy way to turn your local network over HTTPS with intelligent domain routing.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
#
|
|
9
|
-
|
|
8
|
+
# Install dependencies
|
|
9
|
+
bun install
|
|
10
10
|
|
|
11
|
-
#
|
|
12
|
-
|
|
11
|
+
# Build and start the proxy system
|
|
12
|
+
bun run start
|
|
13
13
|
|
|
14
14
|
# Development mode with auto-reload
|
|
15
|
-
|
|
15
|
+
bun run dev
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Build Scripts
|
|
19
19
|
|
|
20
|
-
###
|
|
20
|
+
### Available Commands:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
#
|
|
24
|
-
|
|
23
|
+
# Build TypeScript CLI
|
|
24
|
+
bun run build:ts
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
|
|
26
|
+
# Build Rust proxy binary
|
|
27
|
+
bun run build:rs
|
|
28
28
|
|
|
29
|
-
#
|
|
30
|
-
|
|
29
|
+
# Full build (both TypeScript and Rust)
|
|
30
|
+
bun run build
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
|
|
32
|
+
# Development with hot reload
|
|
33
|
+
bun run dev
|
|
34
34
|
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# Run tests
|
|
39
|
-
npm run test-proxy
|
|
40
|
-
|
|
41
|
-
# Format code
|
|
42
|
-
npm run fmt-proxy
|
|
43
|
-
|
|
44
|
-
# Run linter
|
|
45
|
-
npm run clippy-proxy
|
|
46
|
-
|
|
47
|
-
# Run proxy directly (for testing)
|
|
48
|
-
npm run run-proxy
|
|
35
|
+
# Production start
|
|
36
|
+
bun run start
|
|
49
37
|
```
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
# Build and run (development)
|
|
55
|
-
npm run proxy:dev
|
|
39
|
+
## Architecture
|
|
56
40
|
|
|
57
|
-
|
|
58
|
-
npm run proxy:prod
|
|
41
|
+
The FBI Proxy consists of three main components:
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
- **TypeScript CLI** (`ts/cli.ts`): Orchestrates the entire system, manages Caddy and Rust proxy processes
|
|
44
|
+
- **Rust Proxy Server** (`proxy.rs`): High-performance HTTP/WebSocket proxy using Hyper framework
|
|
45
|
+
- **Caddy Server**: Handles TLS termination, SSL certificates, and domain routing
|
|
63
46
|
|
|
64
|
-
|
|
47
|
+
### How It Works
|
|
65
48
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
1. **CLI** downloads/manages Caddy binary and builds the Rust proxy
|
|
50
|
+
2. **Caddy** receives incoming HTTPS requests and forwards them to the Rust proxy
|
|
51
|
+
3. **Rust Proxy** intelligently routes requests based on hostname patterns
|
|
69
52
|
|
|
70
53
|
## Development Workflow
|
|
71
54
|
|
|
72
55
|
### First Time Setup:
|
|
73
56
|
|
|
74
57
|
```bash
|
|
75
|
-
# 1. Install dependencies
|
|
76
|
-
|
|
58
|
+
# 1. Install dependencies (requires Bun)
|
|
59
|
+
bun install
|
|
77
60
|
|
|
78
|
-
# 2.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
# 3. Start development
|
|
82
|
-
npm run dev
|
|
61
|
+
# 2. Start development (automatically builds and runs)
|
|
62
|
+
bun run dev
|
|
83
63
|
```
|
|
84
64
|
|
|
85
65
|
### Daily Development:
|
|
86
66
|
|
|
87
67
|
```bash
|
|
88
|
-
#
|
|
89
|
-
|
|
68
|
+
# Development with hot reload for both Caddy and Rust
|
|
69
|
+
bun run dev
|
|
90
70
|
|
|
91
|
-
# Or
|
|
92
|
-
|
|
93
|
-
|
|
71
|
+
# Or run individual components:
|
|
72
|
+
bun run dev:caddy # Start Caddy with file watching
|
|
73
|
+
bun run dev:rs # Start Rust proxy with bacon (auto-rebuild)
|
|
94
74
|
```
|
|
95
75
|
|
|
96
|
-
###
|
|
76
|
+
### Production Deployment:
|
|
97
77
|
|
|
98
78
|
```bash
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
npm run check-proxy # Verify compilation
|
|
102
|
-
npm run test-proxy # Run tests
|
|
79
|
+
bun run build # Build optimized binaries
|
|
80
|
+
bun run start # Start production services
|
|
103
81
|
```
|
|
104
82
|
|
|
105
|
-
|
|
83
|
+
## Prerequisites
|
|
106
84
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
85
|
+
- **Bun**: JavaScript runtime and package manager (install from https://bun.sh/)
|
|
86
|
+
- **Rust**: For building the proxy binary (install from https://rustup.rs/)
|
|
87
|
+
- **Caddy**: Automatically downloaded by the CLI if not found
|
|
111
88
|
|
|
112
|
-
##
|
|
89
|
+
## Routing Features
|
|
90
|
+
|
|
91
|
+
The FBI Proxy supports intelligent hostname-based routing with the following patterns:
|
|
92
|
+
|
|
93
|
+
### 1. Port Forwarding
|
|
94
|
+
|
|
95
|
+
- `https://3000.fbi.com` → `http://localhost:3000`
|
|
96
|
+
- `https://8080.fbi.com` → `http://localhost:8080`
|
|
113
97
|
|
|
114
|
-
|
|
115
|
-
- **Caddy**: Web server for TLS termination
|
|
116
|
-
- **Bun**: Runtime for TypeScript CLI
|
|
98
|
+
### 2. Host--Port Forwarding
|
|
117
99
|
|
|
118
|
-
|
|
100
|
+
- `https://localhost--3000.fbi.com` → `http://localhost:3000`
|
|
101
|
+
- `https://myserver--8080.fbi.com` → `http://myserver:8080`
|
|
119
102
|
|
|
120
|
-
|
|
121
|
-
2. Host Forwarder, https://[*].[host].fbi.com proxies to [host] with url https://[*].fbi.com
|
|
122
|
-
3. Host:Port forwarder https://[host]--[port].fbi.com proxies to http://[host]:[port]
|
|
123
|
-
4. Configurable host alias
|
|
103
|
+
### 3. Subdomain Hoisting
|
|
124
104
|
|
|
125
|
-
|
|
105
|
+
- `https://api.myserver.fbi.com` → `http://myserver:80` (with Host: `api`)
|
|
106
|
+
- `https://admin.localhost.fbi.com` → `http://localhost:80` (with Host: `admin`)
|
|
126
107
|
|
|
127
|
-
|
|
108
|
+
### 4. Direct Host Forwarding
|
|
128
109
|
|
|
129
|
-
|
|
110
|
+
- `https://myserver.fbi.com` → `http://myserver:80`
|
|
111
|
+
- `https://localhost.fbi.com` → `http://localhost:80`
|
|
112
|
+
|
|
113
|
+
### WebSocket Support
|
|
114
|
+
|
|
115
|
+
All routing patterns support WebSocket connections with automatic upgrade handling.
|
|
116
|
+
|
|
117
|
+
## Configuration
|
|
118
|
+
|
|
119
|
+
### Environment Variables
|
|
130
120
|
|
|
131
121
|
```env
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
FBIHOST="fbi.com" # Default domain (configurable via --fbihost)
|
|
123
|
+
FBIPROXY_PORT="24306" # Internal proxy port (auto-assigned)
|
|
134
124
|
```
|
|
135
125
|
|
|
136
|
-
|
|
137
|
-
activitywatch=3000
|
|
138
|
-
activitywatch=3000
|
|
139
|
-
activitywatch=3000
|
|
126
|
+
### CLI Options
|
|
140
127
|
|
|
128
|
+
```bash
|
|
129
|
+
bun run ts/cli.ts --help
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
--help Show help message
|
|
133
|
+
--fbihost Set the FBI host (default: fbi.com)
|
|
141
134
|
```
|
|
142
135
|
|
|
143
|
-
|
|
144
|
-
activitywatch: :5600
|
|
136
|
+
## Service Configuration Examples
|
|
145
137
|
|
|
146
|
-
|
|
147
|
-
aw: :5600
|
|
138
|
+
Create custom service mappings by modifying the routing logic or using the built-in patterns:
|
|
148
139
|
|
|
149
|
-
|
|
150
|
-
|
|
140
|
+
```bash
|
|
141
|
+
# Direct port access
|
|
142
|
+
https://3000.fbi.com # → localhost:3000
|
|
143
|
+
https://5173.fbi.com # → localhost:5173 (Vite dev server)
|
|
144
|
+
https://8000.fbi.com # → localhost:8000 (VS Code server)
|
|
145
|
+
|
|
146
|
+
# Named services with custom ports
|
|
147
|
+
https://api--3001.fbi.com # → api:3001
|
|
148
|
+
https://db--5432.fbi.com # → db:5432
|
|
149
|
+
|
|
150
|
+
# Subdomain routing
|
|
151
|
+
# Subdomain routing
|
|
152
|
+
https://admin.app.fbi.com # → app:80 with Host: admin
|
|
153
|
+
https://v2.api.fbi.com # → api:80 with Host: v2
|
|
154
|
+
```
|
|
151
155
|
|
|
152
|
-
|
|
153
|
-
everything: :2489
|
|
156
|
+
## Technical Details
|
|
154
157
|
|
|
155
|
-
|
|
156
|
-
vscode: :8000
|
|
158
|
+
### Rust Proxy Implementation (`proxy.rs`)
|
|
157
159
|
|
|
158
|
-
|
|
160
|
+
The Rust proxy server implements the following routing logic:
|
|
161
|
+
|
|
162
|
+
1. **Number Host Detection**: Pure numeric hosts (e.g., `3000`) route to `localhost:3000`
|
|
163
|
+
2. **Double-Dash Parsing**: `host--port` format routes to `host:port`
|
|
164
|
+
3. **Subdomain Hoisting**: Multi-level domains route to the root domain with subdomain as Host header
|
|
165
|
+
4. **Default Port 80**: Simple hostnames default to port 80
|
|
166
|
+
|
|
167
|
+
### TypeScript CLI (`ts/cli.ts`)
|
|
168
|
+
|
|
169
|
+
The CLI manages:
|
|
170
|
+
|
|
171
|
+
- Binary discovery and building (Rust proxy, Caddy download)
|
|
172
|
+
- Process orchestration with proper signal handling
|
|
173
|
+
- Port management and environment variable passing
|
|
174
|
+
- Hot reloading during development
|
|
175
|
+
|
|
176
|
+
### Caddy Configuration (`Caddyfile`)
|
|
177
|
+
|
|
178
|
+
- Automatic HTTPS with on-demand TLS certificates
|
|
179
|
+
- Regex-based host header matching
|
|
180
|
+
- Reverse proxy configuration with header manipulation
|
|
181
|
+
- Support for wildcard subdomain routing
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT License - see [LICENSE](LICENSE) file for details
|
package/package.json
CHANGED
|
@@ -3,34 +3,69 @@
|
|
|
3
3
|
"module": "ts/cli.ts",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"devDependencies": {
|
|
6
|
-
"@types/bun": "latest",
|
|
7
|
-
"semantic-release": "^22.0.0",
|
|
8
6
|
"@semantic-release/changelog": "^6.0.3",
|
|
9
7
|
"@semantic-release/git": "^10.0.1",
|
|
10
|
-
"@semantic-release/github": "^9.2.0"
|
|
8
|
+
"@semantic-release/github": "^9.2.0",
|
|
9
|
+
"@types/bun": "latest",
|
|
10
|
+
"@types/minimist": "^1.2.5",
|
|
11
|
+
"semantic-release-cargo": "^2.4.0",
|
|
12
|
+
"husky": "^9.1.7",
|
|
13
|
+
"lint-staged": "^16.1.2",
|
|
14
|
+
"prettier": "^3.6.2",
|
|
15
|
+
"semantic-release": "^22.0.0"
|
|
11
16
|
},
|
|
12
17
|
"peerDependencies": {
|
|
13
18
|
"typescript": "^5"
|
|
14
19
|
},
|
|
20
|
+
"files": [
|
|
21
|
+
"release",
|
|
22
|
+
"rs",
|
|
23
|
+
"ts",
|
|
24
|
+
"dist",
|
|
25
|
+
"Caddyfile"
|
|
26
|
+
],
|
|
15
27
|
"dependencies": {
|
|
16
|
-
"@
|
|
28
|
+
"@snomiao/caddy-baron": "^3.0.4",
|
|
29
|
+
"bun": "^1.2.19",
|
|
17
30
|
"caddy-baron": "^3.0.2",
|
|
31
|
+
"from-node-stream": "^0.1.0",
|
|
18
32
|
"get-port": "^7.1.0",
|
|
19
33
|
"hot-memo": "^1.1.1",
|
|
20
34
|
"minimist": "^1.2.8",
|
|
35
|
+
"npm-run-all": "^4.1.5",
|
|
21
36
|
"phpdie": "^1.7.0",
|
|
22
|
-
"
|
|
37
|
+
"promise-all-properties": "^5.0.0",
|
|
38
|
+
"sflow": "^1.23.0",
|
|
39
|
+
"ts-toolbelt": "^9.6.0",
|
|
40
|
+
"tsa-composer": "^1.0.0",
|
|
41
|
+
"zx": "^8.7.2"
|
|
23
42
|
},
|
|
24
43
|
"scripts": {
|
|
25
44
|
"build-cli": "bun build ts/cli.ts --outdir dist",
|
|
26
|
-
"build": "
|
|
27
|
-
"build:ts": "
|
|
28
|
-
"build:
|
|
29
|
-
"
|
|
30
|
-
"
|
|
45
|
+
"build": "run-p build:rs build:ts build:js",
|
|
46
|
+
"build:ts": "tsc",
|
|
47
|
+
"build:js": "bun build ./ts/cli.ts --outdir dist --target node",
|
|
48
|
+
"build:rs": "cargo build --release",
|
|
49
|
+
"dev": "run-p dev:caddy dev:rs",
|
|
50
|
+
"dev:caddy": "./caddy run --watch",
|
|
51
|
+
"dev:ts": "bun --hot ts/cli.ts --dev",
|
|
52
|
+
"dev:rs": "cd rs && bacon run",
|
|
53
|
+
"dev:rs-watch": "cd rs && cargo watch -x run",
|
|
54
|
+
"start": "bun ts/cli.ts",
|
|
55
|
+
"start:caddy": "./caddy run",
|
|
56
|
+
"start:rs": "./target/release/fbi-proxy",
|
|
57
|
+
"prepare": "husky && bunx rustup && bacon --version || cargo install bacon"
|
|
58
|
+
},
|
|
59
|
+
"lint-staged": {
|
|
60
|
+
"*.{ts,js}": [
|
|
61
|
+
"bun --bun prettier --write"
|
|
62
|
+
],
|
|
63
|
+
"*.{json,md,yml,yaml}": [
|
|
64
|
+
"bun --bun prettier --write"
|
|
65
|
+
]
|
|
31
66
|
},
|
|
32
67
|
"bin": {
|
|
33
|
-
"fbi-proxy": "
|
|
68
|
+
"fbi-proxy": "dist/cli.js"
|
|
34
69
|
},
|
|
35
|
-
"version": "1.
|
|
70
|
+
"version": "1.3.0"
|
|
36
71
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fsp from "fs/promises";
|
|
2
|
+
import { getProxyFilename } from "./getProxyFilename";
|
|
3
|
+
import { copyFile } from "fs/promises";
|
|
4
|
+
import { $ } from "./dRun";
|
|
5
|
+
import { mkdir } from "fs/promises";
|
|
6
|
+
|
|
7
|
+
if (import.meta.main) {
|
|
8
|
+
await buildFbiProxy();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function buildFbiProxy({ rebuild = false } = {}) {
|
|
12
|
+
const isWin = process.platform === "win32";
|
|
13
|
+
const binaryName = getProxyFilename();
|
|
14
|
+
|
|
15
|
+
const release = "./release/" + binaryName;
|
|
16
|
+
const built = `./target/release/fbi-proxy${isWin ? ".exe" : ""}`;
|
|
17
|
+
|
|
18
|
+
// return built if exists
|
|
19
|
+
if (!rebuild && (await fsp.exists(built))) {
|
|
20
|
+
return built;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// return release if exists
|
|
24
|
+
if (!rebuild && (await fsp.exists(release))) return release;
|
|
25
|
+
|
|
26
|
+
// build and return built target
|
|
27
|
+
await $`cargo build --release`;
|
|
28
|
+
if (await fsp.exists(built)) return built;
|
|
29
|
+
|
|
30
|
+
throw new Error(
|
|
31
|
+
"Oops, failed to build fbi-proxy binary. Please check your Rust setup.",
|
|
32
|
+
);
|
|
33
|
+
}
|
package/ts/cli.ts
CHANGED
|
@@ -1,138 +1,118 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import getPort from "get-port";
|
|
3
3
|
import minimist from "minimist";
|
|
4
|
-
import
|
|
5
|
-
import { exec } from "child_process";
|
|
4
|
+
import { exec, spawn } from "child_process";
|
|
6
5
|
import path from "path";
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
6
|
+
import tsaComposer from "tsa-composer";
|
|
7
|
+
import { fromStdio } from "from-node-stream";
|
|
8
|
+
import sflow from "sflow";
|
|
9
|
+
import hotMemo from "hot-memo";
|
|
10
|
+
import fsp from "fs/promises";
|
|
11
|
+
import { exists, existsSync } from "fs";
|
|
12
|
+
import { getProxyFilename } from "./getProxyFilename";
|
|
13
|
+
import { DIE } from "phpdie";
|
|
14
|
+
import promiseAllProperties from "promise-all-properties";
|
|
15
|
+
import { buildFbiProxy } from "./buildFbiProxy";
|
|
16
|
+
import { $ } from "./dRun";
|
|
17
|
+
|
|
18
|
+
process.chdir(path.resolve(__dirname, "..")); // Change to project root directory
|
|
19
|
+
|
|
20
|
+
console.log("Preparing Binaries");
|
|
21
|
+
|
|
22
|
+
const downloadCaddy = async () => {
|
|
23
|
+
// use pwdCaddy if already downloaded
|
|
24
|
+
const pwdCaddy = "./caddy";
|
|
25
|
+
|
|
26
|
+
// if ./caddy exists in pwd, return it
|
|
27
|
+
if (await fsp.exists(pwdCaddy)) return pwdCaddy;
|
|
28
|
+
|
|
29
|
+
// or use system caddy if installed, run `caddy --version` to check
|
|
30
|
+
if (await $`caddy --version`.catch(() => false)) {
|
|
31
|
+
return "caddy";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// or if system caddy is not installed, download caddy using caddy-baron
|
|
35
|
+
if (!existsSync(pwdCaddy)) {
|
|
36
|
+
// download latest caddy to ./caddy
|
|
37
|
+
console.log("Downloading Caddy...");
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
await import("../node_modules/caddy-baron/index.mjs");
|
|
40
|
+
|
|
41
|
+
if (!existsSync(pwdCaddy))
|
|
42
|
+
throw new Error(
|
|
43
|
+
"Failed to download Caddy. Please install Caddy manually or check your network connection.",
|
|
44
|
+
);
|
|
45
|
+
}
|
|
17
46
|
|
|
18
|
-
|
|
19
|
-
const root = Bun.fileURLToPath(import.meta.url) + "../";
|
|
20
|
-
const filename =
|
|
21
|
-
{
|
|
22
|
-
"darwin-arm64": "fbi-proxy-darwin",
|
|
23
|
-
"darwin-x64": "fbi-proxy-darwin",
|
|
24
|
-
"linux-arm64": "fbi-proxy-linux-arm64",
|
|
25
|
-
"linux-x64": "fbi-proxy-linux-x64",
|
|
26
|
-
"linux-x86_64": "fbi-proxy-linux-x64",
|
|
27
|
-
"win32-arm64": "fbi-proxy-windows-arm64.exe",
|
|
28
|
-
"win32-x64": "fbi-proxy-windows-x64.exe",
|
|
29
|
-
}[process.platform + "-" + process.arch] || "fbi-proxy-linux-x64";
|
|
30
|
-
|
|
31
|
-
return [path.join(root, "rs/target/release", filename)].find((e) =>
|
|
32
|
-
existsSync(e)
|
|
33
|
-
);
|
|
47
|
+
return pwdCaddy;
|
|
34
48
|
};
|
|
35
49
|
|
|
50
|
+
const { proxy, caddy } = await promiseAllProperties({
|
|
51
|
+
proxy: buildFbiProxy(),
|
|
52
|
+
caddy: downloadCaddy(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
console.log("Running fbi-proxy", JSON.stringify({ caddy, proxy }));
|
|
56
|
+
|
|
36
57
|
// assume caddy is installed, launch proxy server now
|
|
37
58
|
const argv = minimist(process.argv.slice(2), {
|
|
38
59
|
default: {
|
|
39
60
|
dev: false,
|
|
40
61
|
d: false,
|
|
41
|
-
|
|
62
|
+
fbihost: "fbi.com", // Default FBI host
|
|
42
63
|
},
|
|
43
64
|
alias: {
|
|
44
65
|
dev: "d",
|
|
45
|
-
tls: "t",
|
|
46
66
|
},
|
|
67
|
+
boolean: ["dev", "d", "help"],
|
|
47
68
|
});
|
|
48
|
-
console.log(argv);
|
|
69
|
+
// console.log(argv);
|
|
49
70
|
if (argv.help) {
|
|
50
71
|
console.log(`Usage: fbi-proxy [options]
|
|
51
72
|
Options:
|
|
52
|
-
--dev, -d Enable development mode
|
|
53
|
-
--tls, -t Set TLS mode (internal|external)
|
|
54
73
|
--help Show this help message
|
|
74
|
+
--fbihost Set the FBI host (default: fbi.com)
|
|
55
75
|
`);
|
|
56
76
|
process.exit(0);
|
|
57
77
|
}
|
|
58
78
|
|
|
59
|
-
const
|
|
60
|
-
const
|
|
79
|
+
const FBIHOST = argv.fbihost || "fbi.com"; // Default FBI host
|
|
80
|
+
const FBIPROXY_PORT = String(await getPort({ port: 24306 }));
|
|
61
81
|
const proxyProcess = await hotMemo(async () => {
|
|
62
82
|
console.log("Starting Rust proxy server");
|
|
83
|
+
const p = $.opt({
|
|
84
|
+
env: {
|
|
85
|
+
...process.env,
|
|
86
|
+
FBIPROXY_PORT, // Rust proxy server port
|
|
87
|
+
},
|
|
88
|
+
})`${proxy}`.process;
|
|
63
89
|
|
|
64
|
-
// TODO: in production, build and start the Rust proxy server
|
|
65
|
-
// using `cargo build --release` and then run the binary
|
|
66
|
-
const p = await (async () => {
|
|
67
|
-
if (isDev) {
|
|
68
|
-
// TODO: consider switch to bacon, cargo install bacon
|
|
69
|
-
// in dev mode, use cargo watch to run the Rust proxy server
|
|
70
|
-
const p = exec(`cargo watch -x "run --bin proxy"`, {
|
|
71
|
-
env: {
|
|
72
|
-
...process.env,
|
|
73
|
-
PROXY_PORT,
|
|
74
|
-
},
|
|
75
|
-
cwd: path.join(__dirname, "../rs"),
|
|
76
|
-
});
|
|
77
|
-
return p;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const rsTargetDir = path.join(__dirname, "../rs", "target", "release");
|
|
81
|
-
const proxyBinary = process.platform === "win32" ? "proxy.exe" : "proxy";
|
|
82
|
-
const proxyPath = path.join(rsTargetDir, proxyBinary);
|
|
83
|
-
if (!(await exists(proxyPath).catch(() => false))) {
|
|
84
|
-
console.error("Proxy binary not found at " + proxyPath);
|
|
85
|
-
console.error(
|
|
86
|
-
"Please build the Rust proxy server first using `cargo build --release`"
|
|
87
|
-
);
|
|
88
|
-
process.exit(1);
|
|
89
|
-
}
|
|
90
|
-
const p = exec(proxyPath, {
|
|
91
|
-
env: {
|
|
92
|
-
...process.env,
|
|
93
|
-
PROXY_PORT, // Rust proxy server port
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
return p;
|
|
97
|
-
})();
|
|
98
|
-
|
|
99
|
-
p.stdout?.pipe(process.stdout, { end: false });
|
|
100
|
-
p.stderr?.pipe(process.stderr, { end: false });
|
|
101
90
|
p.on("exit", (code) => {
|
|
102
91
|
console.log(`Proxy server exited with code ${code}`);
|
|
103
92
|
process.exit(code || 0);
|
|
104
93
|
});
|
|
105
|
-
|
|
106
|
-
console.log(`Rust proxy server started on port ${PROXY_PORT}`);
|
|
107
94
|
return p;
|
|
108
95
|
});
|
|
109
96
|
|
|
110
97
|
const caddyProcess = await hotMemo(async () => {
|
|
111
|
-
const
|
|
112
|
-
if (!(await exists(Caddyfile).catch(() => false))) {
|
|
113
|
-
console.error("Caddyfile not found at " + Caddyfile);
|
|
114
|
-
console.error(
|
|
115
|
-
"Please create a Caddyfile in the root directory of the project."
|
|
116
|
-
);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
console.log("Starting Caddy");
|
|
120
|
-
const p = exec(`caddy run ${isDev ? "--watch" : ""} --config ${Caddyfile}`, {
|
|
98
|
+
const p = $.opt({
|
|
121
99
|
env: {
|
|
122
100
|
...process.env,
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
FBIPROXY_PORT, // Rust proxy server port
|
|
102
|
+
FBIHOST,
|
|
125
103
|
},
|
|
126
|
-
|
|
104
|
+
})`${caddy} run`.process;
|
|
105
|
+
p.on("exit", (code) => {
|
|
106
|
+
console.log(`Caddy exited with code ${code}`);
|
|
107
|
+
process.exit(code || 0);
|
|
127
108
|
});
|
|
128
|
-
// p.stdout?.pipe(process.stdout, { end: false });
|
|
129
|
-
// p.stderr?.pipe(process.stderr, { end: false });
|
|
130
|
-
p.on("exit", (code) => process.exit(code || 0));
|
|
131
|
-
console.log("Caddy started with config at " + Caddyfile);
|
|
132
109
|
return p;
|
|
133
110
|
});
|
|
134
111
|
|
|
135
112
|
console.log("all done");
|
|
113
|
+
// show process pids
|
|
114
|
+
console.log(`Proxy server PID: ${proxyProcess.pid}`);
|
|
115
|
+
console.log(`Caddy server PID: ${caddyProcess.pid}`);
|
|
136
116
|
|
|
137
117
|
const exit = () => {
|
|
138
118
|
console.log("Shutting down...");
|