Skip to content

Commit

Permalink
fix: Support IPv6 when remote recording
Browse files Browse the repository at this point in the history
  • Loading branch information
dividedmind committed Dec 8, 2023
1 parent ab45c0b commit c7b5134
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 56 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,6 @@
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/exec": "^5.0.0",
"@semantic-release/git": "^9.0.0",
"@types/bent": "^7.3.2",
"@types/chai-as-promised": "^7.1.5",
"@types/chai-fs": "^2.0.2",
"@types/fs-extra": "^9.0.13",
Expand Down Expand Up @@ -496,7 +495,6 @@
"@appland/scanner": "^1.83.0",
"@appland/sequence-diagram": "^1.11.0",
"@yarnpkg/parsers": "^3.0.0-rc.45",
"bent": "^7.3.12",
"bootstrap": "^4.5.3",
"bootstrap-autocomplete": "^2.3.7",
"diff": "^5.1.0",
Expand Down
5 changes: 4 additions & 1 deletion src/actions/remoteRecording.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ export default class RemoteRecording {
);
this.onBeginRecording(recordingUrl);
} catch (e) {
vscode.window.showErrorMessage(`The endpoint does not support AppMap recording`);
const err = e as Error;
vscode.window.showErrorMessage(
`Failed to start recording on ${recordingUrl}: ${err.message}`
);
return;
}

Expand Down
61 changes: 38 additions & 23 deletions src/actions/remoteRecordingClient.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,50 @@
import bent, { NodeResponse } from 'bent';
import http, { type IncomingMessage } from 'node:http';
import https from 'node:https';

export default class RemoteRecordingClient {
private static readonly RECORDING_URI = '/_appmap/record';

static async start(baseURL: string): Promise<number> {
const getStream = bent(baseURL, 'POST', 200, 409);
const stream = (await getStream(this.RECORDING_URI)) as {
statusCode: number;
};

return stream.statusCode;
return (await recordRequest(baseURL, 'POST', [200, 409])).statusCode;
}

static async getStatus(baseURL: string): Promise<boolean> {
const request = bent(baseURL, 'GET', 200);
const response = (await request(this.RECORDING_URI)) as NodeResponse;
const body = (await response.json()) as { enabled: boolean };

return body.enabled;
const response = await recordRequest(baseURL, 'GET', [200]);
const body = await readJSON(response);
if (typeof body === 'object' && body && 'enabled' in body && typeof body.enabled === 'boolean')
return body.enabled;
else throw new Error(`Unexpected body: ${body}`);
}

static async stop(baseURL: string): Promise<unknown> {
const getStream = bent(baseURL, 'DELETE', 200, 404);
const stream = (await getStream(this.RECORDING_URI)) as {
statusCode: number;
json;
};

static async stop(baseURL: string): Promise<{ statusCode: number; body: unknown }> {
const response = await recordRequest(baseURL, 'DELETE', [200, 404]);
return {
statusCode: stream.statusCode,
body: await stream.json(),
statusCode: response.statusCode,
body: await readJSON(response).catch(() => undefined),
};
}
}

function recordRequest(
baseURL: string,
method: string,
codes: number[]
): Promise<IncomingMessage & { statusCode: number }> {
if (!baseURL.startsWith('http')) baseURL = `http://${baseURL}`;
const url = new URL('_appmap/record', baseURL);
const proto = url.protocol === 'https:' ? https : http;
return new Promise((resolve, reject) =>
proto
.request(url, { method }, (response) =>
response.statusCode && codes.includes(response.statusCode)
? resolve(response as IncomingMessage & { statusCode: number })
: reject(new Error(`unexpected response code: ${response.statusCode}`))
)
.once('error', reject)
.end()
);
}

async function readJSON(res: NodeJS.ReadableStream): Promise<unknown> {
const chunks: string[] = [];
for await (const chunk of res) chunks.push(chunk.toString());
return JSON.parse(chunks.join(''));
}
2 changes: 1 addition & 1 deletion test/unit/actions/remoteRecording.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('remote recording', () => {
});

it('returns false on command stop with a 404 response', async () => {
sinon.stub(RemoteRecordingClient, 'stop').resolves({ statusCode: 404 });
sinon.stub(RemoteRecordingClient, 'stop').resolves({ statusCode: 404, body: undefined });
const response = await remoteRecording.stop('http://localhost:8080/');
assert(!response);
});
Expand Down
29 changes: 0 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1843,15 +1843,6 @@ __metadata:
languageName: node
linkType: hard

"@types/bent@npm:^7.3.2":
version: 7.3.2
resolution: "@types/bent@npm:7.3.2"
dependencies:
"@types/node": "*"
checksum: af28b4e77fce3de928ac4b90568971b73970351d3167bf89418c363ab207164516745b477ed803c90b2aaf81d46487e298e4fa8febd45b2d109e80872670c75f
languageName: node
linkType: hard

"@types/btoa-lite@npm:^1.0.0":
version: 1.0.0
resolution: "@types/btoa-lite@npm:1.0.0"
Expand Down Expand Up @@ -2816,7 +2807,6 @@ __metadata:
"@semantic-release/changelog": ^5.0.1
"@semantic-release/exec": ^5.0.0
"@semantic-release/git": ^9.0.0
"@types/bent": ^7.3.2
"@types/chai-as-promised": ^7.1.5
"@types/chai-fs": ^2.0.2
"@types/fs-extra": ^9.0.13
Expand All @@ -2838,7 +2828,6 @@ __metadata:
"@vscode/vsce": ^2.19.0
"@vue/compiler-sfc": ^3.2.37
"@yarnpkg/parsers": ^3.0.0-rc.45
bent: ^7.3.12
bootstrap: ^4.5.3
bootstrap-autocomplete: ^2.3.7
browserify-fs: ^1.0.0
Expand Down Expand Up @@ -3208,17 +3197,6 @@ __metadata:
languageName: node
linkType: hard

"bent@npm:^7.3.12":
version: 7.3.12
resolution: "bent@npm:7.3.12"
dependencies:
bytesish: ^0.4.1
caseless: ~0.12.0
is-stream: ^2.0.0
checksum: b0c08f6fa204baec0841021f5cff49aba929bbff28089bbac0d446122aa5f8e10b1b6837310b0800717cbf431c984bead2ed130bec35045d4ea688d896458d54
languageName: node
linkType: hard

"big-integer@npm:^1.6.17":
version: 1.6.48
resolution: "big-integer@npm:1.6.48"
Expand Down Expand Up @@ -3599,13 +3577,6 @@ __metadata:
languageName: node
linkType: hard

"bytesish@npm:^0.4.1":
version: 0.4.4
resolution: "bytesish@npm:0.4.4"
checksum: 50a6c9423f66fff984676ee1d3c5f12d2a23830cb5de81abc597415aa2f51cc617b251d660eede10b8e45bf3a3a5c31d4be467ec69888f31ccc66e90cb586ad5
languageName: node
linkType: hard

"cac@npm:^6.7.12":
version: 6.7.14
resolution: "cac@npm:6.7.14"
Expand Down

0 comments on commit c7b5134

Please sign in to comment.