Skip to content

Commit 95e8723

Browse files
committed
fix: index wire files through the open handle and de-quadratic the remote-control rewriter
syncWireFile now opens the wire file first and stats that handle, so the size and identity the indexer trusts belong to the same fd the reads use. The remote-control response rewriter replaces its trailing-slash and head-tag regex scans with linear scans, removing the polynomial-input findings. elkaix <melkholy@techmatrix.com>
1 parent cf930e8 commit 95e8723

2 files changed

Lines changed: 37 additions & 21 deletions

File tree

packages/agent-gateway/src/search/indexCore.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createHash } from 'node:crypto';
2-
import { open, readFile, readdir, stat } from 'node:fs/promises';
2+
import { open, readFile, readdir, stat, type FileHandle } from 'node:fs/promises';
33
import { join, relative } from 'node:path';
44

55
import {
@@ -665,11 +665,21 @@ export class SearchIndexCore {
665665
file: WireFileRef,
666666
budget: SyncRoundBudget,
667667
): Promise<SessionSyncResult> {
668+
let handle: FileHandle;
669+
try {
670+
handle = await open(file.path, 'r');
671+
} catch (error) {
672+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
673+
return { truncated: false, failed: false };
674+
}
675+
return { truncated: false, failed: true, error: errorMessage(error) };
676+
}
668677
let st: { size: number; mtimeMs: number; ino: number };
669678
try {
670-
st = await stat(file.path);
671-
} catch {
672-
return { truncated: false, failed: false };
679+
st = await handle.stat();
680+
} catch (error) {
681+
await handle.close();
682+
return { truncated: false, failed: true, error: errorMessage(error) };
673683
}
674684
const size = st.size;
675685
const metaKey = fileMetaKey(summary.id, file.path);
@@ -730,15 +740,10 @@ export class SearchIndexCore {
730740
if (legacyKey !== null) ops.push({ op: 'del', key: legacyKey });
731741
await db.batch(ops);
732742
}
743+
await handle.close();
733744
return { truncated: false, failed: false };
734745
}
735746

736-
let handle: Awaited<ReturnType<typeof open>>;
737-
try {
738-
handle = await open(file.path, 'r');
739-
} catch (error) {
740-
return { truncated: false, failed: true, error: errorMessage(error) };
741-
}
742747
const ops: BatchInputOp<SearchDoc>[] = [];
743748
let byteCursor = offset;
744749
let position = offset;

packages/remote-control/src/remote-control.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export function buildRemoteControlUrl(
153153
relayOrigin = REMOTE_CONTROL_RELAY_ORIGIN,
154154
): string {
155155
const url = new URL(relayOrigin);
156-
const relayPath = url.pathname.replace(/\/+$/, '');
156+
const relayPath = stripTrailingSlashes(url.pathname);
157157
const devicePath = `${relayPath}/devices/${encodeURIComponent(deviceId)}`;
158158
url.pathname =
159159
sessionId === undefined
@@ -231,23 +231,34 @@ export function filterForwardRequestHeaders(
231231
return result;
232232
}
233233

234+
function stripTrailingSlashes(value: string): string {
235+
let end = value.length;
236+
while (end > 0 && value.codePointAt(end - 1) === 47) end -= 1;
237+
return end === value.length ? value : value.slice(0, end);
238+
}
239+
240+
function findHeadTagEnd(text: string): number {
241+
const start = /<head(?=[\s>])/i.exec(text);
242+
if (start === null) return -1;
243+
const close = text.indexOf('>', start.index + 5);
244+
return close === -1 ? -1 : close + 1;
245+
}
246+
234247
export function rewriteRemoteControlResponse(
235248
contentType: string,
236249
body: Buffer,
237250
publicPrefix: string,
238251
): Buffer {
239-
const normalizedPrefix = publicPrefix.replace(/\/+$/, '');
252+
const normalizedPrefix = stripTrailingSlashes(publicPrefix);
240253
if (contentType.toLowerCase().includes('text/html')) {
241254
const prefixLiteral = scriptStringLiteral(normalizedPrefix);
242255
const injected = `<script>(function(){var p=${prefixLiteral};try{sessionStorage.setItem('pythinker-desktop-server-origin',location.origin+p)}catch(e){}var w=function(f){return function(s,t,u){if(typeof u==='string'&&u.charAt(0)==='/'&&u.indexOf(p)!==0)u=p+u;return f.apply(this,[s,t,u])}};history.pushState=w(history.pushState);history.replaceState=w(history.replaceState)})();</script>`;
243256
let text = body.toString('utf8');
244-
const headMatch = /<head(?:\s[^>]*)?>/i.exec(text);
257+
const headEnd = findHeadTagEnd(text);
245258
text =
246-
headMatch === null
259+
headEnd === -1
247260
? injected + text
248-
: text.slice(0, headMatch.index + headMatch[0].length) +
249-
injected +
250-
text.slice(headMatch.index + headMatch[0].length);
261+
: text.slice(0, headEnd) + injected + text.slice(headEnd);
251262
text = text.replaceAll(/\bsrc="\//g, `src="${normalizedPrefix}/`);
252263
text = text.replaceAll(/\bhref="\//g, `href="${normalizedPrefix}/`);
253264
return Buffer.from(text);
@@ -318,7 +329,7 @@ export async function startRemoteControl(
318329
const deviceName = hostname();
319330
const url = buildRemoteControlUrl(deviceId, undefined, relayOrigin);
320331
const lock = await acquireRemoteControlLock(options.homeDir, {
321-
localOrigin: options.localOrigin.replace(/\/+$/, ''),
332+
localOrigin: stripTrailingSlashes(options.localOrigin),
322333
deviceId,
323334
url,
324335
});
@@ -387,7 +398,7 @@ class RemoteControlClient {
387398
readonly localServerToken: () => string;
388399
},
389400
) {
390-
this.localOrigin = options.localOrigin.replace(/\/+$/, '');
401+
this.localOrigin = stripTrailingSlashes(options.localOrigin);
391402
this.localServerToken = options.localServerToken;
392403
this.clientVersion = options.clientVersion;
393404
this.relayOrigin = options.relayOrigin;
@@ -758,7 +769,7 @@ class RemoteControlClient {
758769
}
759770

760771
private publicPrefix(): string {
761-
const relayPath = new URL(this.relayOrigin).pathname.replace(/\/+$/, '');
772+
const relayPath = stripTrailingSlashes(new URL(this.relayOrigin).pathname);
762773
return `${relayPath}/devices/${encodeURIComponent(this.deviceId)}`;
763774
}
764775

@@ -1050,7 +1061,7 @@ function isValidCloseCode(code: number): boolean {
10501061
function relayWebSocketUrl(origin: string, path: string): string {
10511062
const url = new URL(origin);
10521063
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
1053-
const relayPath = url.pathname.replace(/\/+$/, '');
1064+
const relayPath = stripTrailingSlashes(url.pathname);
10541065
const [pathname, query] = path.split('?', 2);
10551066
url.pathname = `${relayPath}${pathname}`;
10561067
url.search = query === undefined ? '' : query;

0 commit comments

Comments
 (0)