Skip to content

Commit 61b0a45

Browse files
committed
fix(respect): binary data is destroyed when consumed with text
1 parent e9bdae8 commit 61b0a45

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { isBinaryContentType } from '../isBinaryContentType.js';
2+
3+
describe('isBinaryContentType', () => {
4+
it('should return true for binary content types', () => {
5+
expect(isBinaryContentType('application/octet-stream')).toBe(true);
6+
expect(isBinaryContentType('application/pdf')).toBe(true);
7+
expect(isBinaryContentType('image/png')).toBe(true);
8+
expect(isBinaryContentType('image/jpeg')).toBe(true);
9+
expect(isBinaryContentType('audio/mpeg')).toBe(true);
10+
expect(isBinaryContentType('video/mp4')).toBe(true);
11+
expect(isBinaryContentType('application/zip')).toBe(true);
12+
expect(isBinaryContentType('application/x-zip-compressed')).toBe(true);
13+
expect(isBinaryContentType('application/gzip')).toBe(true);
14+
expect(isBinaryContentType('application/x-gzip')).toBe(true);
15+
expect(isBinaryContentType('application/x-bzip2')).toBe(true);
16+
expect(isBinaryContentType('application/x-tar')).toBe(true);
17+
expect(isBinaryContentType('application/x-rar-compressed')).toBe(true);
18+
expect(isBinaryContentType('application/x-7z-compressed')).toBe(true);
19+
expect(
20+
isBinaryContentType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
21+
).toBe(true);
22+
expect(isBinaryContentType('application/vnd.ms-excel')).toBe(true);
23+
expect(isBinaryContentType('application/vnd.ms-powerpoint')).toBe(true);
24+
expect(isBinaryContentType('application/msword')).toBe(true);
25+
expect(isBinaryContentType('application/x-shockwave-flash')).toBe(true);
26+
expect(isBinaryContentType('application/x-font-ttf')).toBe(true);
27+
expect(isBinaryContentType('font/woff2')).toBe(true);
28+
});
29+
});

packages/respect-core/src/utils/api-fetcher.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { getResponseSchema } from '../modules/description-parser/index.js';
1717
import { collectSecretFields } from '../modules/flow-runner/index.js';
1818
import { parseWwwAuthenticateHeader } from './digest-auth/parse-www-authenticate-header.js';
1919
import { generateDigestAuthHeader } from './digest-auth/generate-digest-auth-header.js';
20+
import { isBinaryContentType } from './isBinaryContentType.js';
2021

2122
import type { RequestData } from '../modules/flow-runner/index.js';
2223

@@ -343,12 +344,10 @@ export class ApiFetcher implements IFetcher {
343344
});
344345

345346
responseTime = Math.ceil(performance.now() - startTime);
346-
responseBody = await fetchResult.text();
347347
} else {
348348
// REGULAR FETCH
349349
fetchResult = await customFetch(urlToFetch, fetchParams);
350350
responseTime = Math.ceil(performance.now() - startTime);
351-
responseBody = await fetchResult.text();
352351
}
353352

354353
if (!fetchResult) {
@@ -358,6 +357,14 @@ export class ApiFetcher implements IFetcher {
358357
const [responseContentType] = fetchResult.headers.get('content-type')?.split(';') || [
359358
'application/json',
360359
];
360+
361+
// Handle response body based on content type
362+
if (isBinaryContentType(responseContentType)) {
363+
const arrayBuffer = await fetchResult.arrayBuffer();
364+
responseBody = Buffer.from(arrayBuffer).toString('base64');
365+
} else {
366+
responseBody = await fetchResult.text();
367+
}
361368
const transformedBody = responseBody
362369
? isJsonContentType(responseContentType)
363370
? JSON.parse(responseBody)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export function isBinaryContentType(contentType: string): boolean {
2+
const binaryTypes = [
3+
'application/octet-stream',
4+
'application/pdf',
5+
'image/',
6+
'audio/',
7+
'video/',
8+
'application/zip',
9+
'application/x-zip-compressed',
10+
'application/gzip',
11+
'application/x-gzip',
12+
'application/x-bzip2',
13+
'application/x-tar',
14+
'application/x-rar-compressed',
15+
'application/x-7z-compressed',
16+
'application/vnd.openxmlformats-officedocument',
17+
'application/vnd.ms-excel',
18+
'application/vnd.ms-powerpoint',
19+
'application/msword',
20+
'application/x-shockwave-flash',
21+
'application/x-font-',
22+
'font/',
23+
'application/x-font-ttf',
24+
];
25+
26+
return binaryTypes.some((type) => contentType.startsWith(type));
27+
}

0 commit comments

Comments
 (0)