Skip to content

Commit 00de082

Browse files
committed
Add proper handling of binary responses
msw doesn't seem to support binary responses because it decodes them to a UTF-8 string. To work around that, we will do a separate fetch of the file and save that.
1 parent 5a76df8 commit 00de082

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

extensions/ql-vscode/src/mocks/recorder.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { SetupServerApi } from 'msw/node';
66
import { IsomorphicResponse } from '@mswjs/interceptors';
77

88
import { Headers } from 'headers-polyfill';
9+
import fetch from 'node-fetch';
910

1011
import { DisposableObject } from '../pure/disposable-object';
1112

@@ -102,10 +103,14 @@ export class Recorder extends DisposableObject {
102103
}
103104

104105
private onRequestStart(request: MockedRequest): void {
106+
if (request.headers.has('x-vscode-codeql-msw-bypass')) {
107+
return;
108+
}
109+
105110
this.allRequests.set(request.id, request);
106111
}
107112

108-
private onResponseBypass(response: IsomorphicResponse, requestId: string): void {
113+
private async onResponseBypass(response: IsomorphicResponse, requestId: string): Promise<void> {
109114
const request = this.allRequests.get(requestId);
110115
this.allRequests.delete(requestId);
111116
if (!request) {
@@ -116,7 +121,7 @@ export class Recorder extends DisposableObject {
116121
return;
117122
}
118123

119-
const gitHubApiRequest = createGitHubApiRequest(request.url.toString(), response.status, response.body, response.headers);
124+
const gitHubApiRequest = await createGitHubApiRequest(request.url.toString(), response.status, response.body, response.headers);
120125
if (!gitHubApiRequest) {
121126
return;
122127
}
@@ -125,7 +130,7 @@ export class Recorder extends DisposableObject {
125130
}
126131
}
127132

128-
function createGitHubApiRequest(url: string, status: number, body: string, headers: Headers): GitHubApiRequest | undefined {
133+
async function createGitHubApiRequest(url: string, status: number, body: string, headers: Headers): Promise<GitHubApiRequest | undefined> {
129134
if (!url) {
130135
return undefined;
131136
}
@@ -183,14 +188,25 @@ function createGitHubApiRequest(url: string, status: number, body: string, heade
183188
// if url is a download URL for a variant analysis result, then it's a get-variant-analysis-repoResult.
184189
const repoDownloadMatch = url.match(/objects-origin\.githubusercontent\.com\/codeql-query-console\/codeql-variant-analysis-repo-tasks\/\d+\/(?<repositoryId>\d+)/);
185190
if (repoDownloadMatch?.groups?.repositoryId) {
191+
// msw currently doesn't support binary response bodies, so we need to download this separately
192+
// see https://github.com/mswjs/interceptors/blob/15eafa6215a328219999403e3ff110e71699b016/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts#L24-L33
193+
// Essentially, mws is trying to decode a ZIP file as UTF-8 which changes the bytes and corrupts the file.
194+
const response = await fetch(url, {
195+
headers: {
196+
// We need to ensure we don't end up in an infinite loop, since this request will also be intercepted
197+
'x-vscode-codeql-msw-bypass': 'true',
198+
},
199+
});
200+
const responseBuffer = await response.buffer();
201+
186202
return {
187203
request: {
188204
kind: RequestKind.GetVariantAnalysisRepoResult,
189205
repositoryId: parseInt(repoDownloadMatch.groups.repositoryId, 10),
190206
},
191207
response: {
192208
status,
193-
body: Buffer.from(body),
209+
body: responseBuffer,
194210
contentType: headers.get('content-type') ?? 'application/octet-stream',
195211
}
196212
};

extensions/ql-vscode/src/mocks/request-handlers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ function createGetVariantAnalysisRepoResultRequestHandler(requests: GitHubApiReq
144144
if (scenarioRequest.response.body) {
145145
return res(
146146
ctx.status(scenarioRequest.response.status),
147+
ctx.set('Content-Type', scenarioRequest.response.contentType),
147148
ctx.body(scenarioRequest.response.body),
148149
);
149150
} else {

0 commit comments

Comments
 (0)