build works now
Build & Release binary / build (push) Successful in 26m20s

This commit is contained in:
2026-08-22 16:14:56 +05:00
parent 72e07f6a01
commit 6768b0a5b2
14 changed files with 506 additions and 22 deletions
+38 -12
View File
@@ -1,9 +1,13 @@
/*
* Single-file binary entry point (compiled with `bun build --compile`).
*
* Not part of upstream. Copied to the server submodule root by scripts/apply.sh.
* The built UI is embedded into the binary as `ui.tar.gz` (created by
* scripts/build.sh) and extracted to a temp dir on first run.
* Not part of upstream. Copied to the server clone root by scripts/patch.sh.
* Two archives are embedded into the binary by scripts/build.sh and extracted to
* a temp dir on first run:
* - ui.tar.gz the built web UI, served over HTTP
* - overrides.tar.gz the interception overrides tree (terminal shims, the JVM
* agent, frida, the browser webextension) that upstream
* expects to find on disk at APP_ROOT/overrides
*
* Usage: httptoolkit [--port 8080] [--server-port 45457] [--mockttp-port 45456] [--no-open]
*/
@@ -17,11 +21,16 @@ import * as fs from 'fs';
import * as fsp from 'fs/promises';
import { x as extractTar } from 'tar';
import { startHtkApp } from './src/htk-app';
import { SERVER_VERSION } from './src/constants';
// Embedded UI bundle. Resolves to a path Bun can read from the compiled binary:
// Embedded archives. These resolve to paths Bun can read from the compiled binary:
import uiArchive from './ui.tar.gz' with { type: 'file' };
import overridesArchive from './overrides.tar.gz' with { type: 'file' };
// Deliberately NOT imported from './src/constants': that module computes APP_ROOT
// at load time, and we have to set HTK_APP_ROOT before it is ever evaluated (see
// main()). package.json carries the version without pulling in any of that.
import pkg from './package.json';
const SERVER_VERSION: string = pkg.version;
function printHelp() {
console.log(`HTTP Toolkit (self-hosted single binary) v${SERVER_VERSION}
@@ -64,16 +73,18 @@ function parseArgs(argv: string[]) {
return opts;
}
async function extractUi(): Promise<string> {
const dir = path.join(os.tmpdir(), `httptoolkit-ui-${SERVER_VERSION}`);
// Extract one embedded tarball into `dir`, unless it's already there for this
// version. Modes are preserved, which matters: overrides/path holds executable
// shims that only work if they stay +x.
async function extractArchive(archivePath: string, dir: string): Promise<string> {
const marker = path.join(dir, '.extracted');
if (fs.existsSync(marker)) return dir; // already extracted for this version
await fsp.rm(dir, { recursive: true, force: true });
await fsp.mkdir(dir, { recursive: true });
const bytes = new Uint8Array(await Bun.file(uiArchive).arrayBuffer());
const tmpArchive = path.join(dir, 'ui.tar.gz');
const bytes = new Uint8Array(await Bun.file(archivePath).arrayBuffer());
const tmpArchive = path.join(dir, 'archive.tar.gz');
await fsp.writeFile(tmpArchive, bytes);
await extractTar({ file: tmpArchive, cwd: dir });
@@ -84,7 +95,22 @@ async function extractUi(): Promise<string> {
async function main() {
const opts = parseArgs(process.argv.slice(2));
const uiDir = await extractUi();
// One app root per version, laid out the way upstream expects to find it:
// <tmp>/httptoolkit-<version>/ui
// <tmp>/httptoolkit-<version>/overrides
const appRoot = path.join(os.tmpdir(), `httptoolkit-${SERVER_VERSION}`);
const uiDir = path.join(appRoot, 'ui');
await extractArchive(uiArchive, uiDir);
await extractArchive(overridesArchive, path.join(appRoot, 'overrides'));
// Must be set before ./src/constants is evaluated, since APP_ROOT (and hence
// OVERRIDES_DIR) is computed once at module load. That's why the app is pulled
// in with a dynamic import here rather than a static one at the top of the file.
process.env.HTK_APP_ROOT = appRoot;
const { startHtkApp } = await import('./src/htk-app');
await startHtkApp({ ...opts, uiDir });
}