-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Support IPv6 when remote recording
- Loading branch information
1 parent
b2a38ad
commit ddf8cd5
Showing
5 changed files
with
43 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('')); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters