Skip to content

Commit 980c4f2

Browse files
committed
Broke down the regex into chunks and optimized tests
1 parent 2627663 commit 980c4f2

File tree

3 files changed

+59
-72
lines changed

3 files changed

+59
-72
lines changed

packages/event-handler/src/rest/constants.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,12 @@ export const UNSAFE_CHARS = '%<> \\[\\]{}|^';
9191
/**
9292
* Match for compressible content type.
9393
*/
94-
export const COMPRESSIBLE_CONTENT_TYPE_REGEX =
95-
/^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
94+
export const COMPRESSIBLE_CONTENT_TYPE_REGEX = {
95+
COMMON: /^\s*application\/json(?:[;\s]|$)/i,
96+
OCCASIONAL:
97+
/^\s*(?:text\/(?:html|plain|css)|application\/(?:xml|javascript)|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i,
98+
RARE: /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex)(?:[;\s]|$)/i,
99+
};
96100

97101
export const CACHE_CONTROL_NO_TRANSFORM_REGEX =
98102
/(?:^|,)\s*?no-transform\s*?(?:,|$)/i;

packages/event-handler/src/rest/middleware/compress.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ const compress = (options?: CompressionOptions): Middleware => {
102102

103103
const shouldCompress = (res: Response) => {
104104
const type = res.headers.get('content-type');
105-
return type && COMPRESSIBLE_CONTENT_TYPE_REGEX.test(type);
105+
return (
106+
type &&
107+
(COMPRESSIBLE_CONTENT_TYPE_REGEX.COMMON.test(type) ||
108+
COMPRESSIBLE_CONTENT_TYPE_REGEX.OCCASIONAL.test(type) ||
109+
COMPRESSIBLE_CONTENT_TYPE_REGEX.RARE.test(type))
110+
);
106111
};
107112

108113
const shouldTransform = (res: Response) => {

packages/event-handler/tests/unit/rest/middleware/compress.test.ts

Lines changed: 47 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
import context from '@aws-lambda-powertools/testing-utils/context';
22
import { Router } from 'src/rest/Router.js';
3-
import { describe, expect, it } from 'vitest';
3+
import { beforeEach, describe, expect, it } from 'vitest';
44
import { compress } from '../../../../src/rest/middleware/index.js';
55
import { createSettingHeadersMiddleware, createTestEvent } from '../helpers.js';
66

77
describe('Compress Middleware', () => {
8+
const event = createTestEvent('/test', 'GET');
9+
let app: Router;
10+
const body = { test: 'x'.repeat(2000) };
11+
12+
beforeEach(() => {
13+
app = new Router();
14+
app.use(compress());
15+
app.use(
16+
createSettingHeadersMiddleware({
17+
'content-length': '2000',
18+
})
19+
);
20+
});
21+
822
it('compresses response when conditions are met', async () => {
923
// Prepare
10-
const event = createTestEvent('/test', 'GET');
11-
const app = new Router();
12-
app.get(
13-
'/test',
14-
[
15-
compress(),
16-
createSettingHeadersMiddleware({
17-
'content-length': '2000',
18-
}),
19-
],
20-
async () => {
21-
return { test: 'x'.repeat(2000) };
22-
}
23-
);
24+
app.get('/test', async () => {
25+
return body;
26+
});
2427

2528
// Act
2629
const result = await app.resolve(event, context);
@@ -32,9 +35,8 @@ describe('Compress Middleware', () => {
3235

3336
it('skips compression when content is below threshold', async () => {
3437
// Prepare
35-
const event = createTestEvent('/test', 'GET');
36-
const app = new Router();
37-
app.get(
38+
const application = new Router();
39+
application.get(
3840
'/test',
3941
[
4042
compress({ threshold: 1024 }),
@@ -48,41 +50,30 @@ describe('Compress Middleware', () => {
4850
);
4951

5052
// Act
51-
const result = await app.resolve(event, context);
53+
const result = await application.resolve(event, context);
5254

5355
// Assess
5456
expect(result.headers?.['content-encoding']).toBeUndefined();
5557
});
5658

5759
it('skips compression for HEAD requests', async () => {
5860
// Prepare
59-
const event = createTestEvent('/test', 'HEAD');
60-
const app = new Router();
61-
app.head(
62-
'/test',
63-
[
64-
compress(),
65-
createSettingHeadersMiddleware({
66-
'content-length': '2000',
67-
}),
68-
],
69-
async () => {
70-
return { test: 'x'.repeat(2000) };
71-
}
72-
);
61+
const headEvent = createTestEvent('/test', 'HEAD');
62+
app.head('/test', async () => {
63+
return body;
64+
});
7365

7466
// Act
75-
const result = await app.resolve(event, context);
67+
const result = await app.resolve(headEvent, context);
7668

7769
// Assess
7870
expect(result.headers?.['content-encoding']).toBeUndefined();
7971
});
8072

8173
it('skips compression when already encoded', async () => {
8274
// Prepare
83-
const event = createTestEvent('/test', 'GET');
84-
const app = new Router();
85-
app.get(
75+
const application = new Router();
76+
application.get(
8677
'/test',
8778
[
8879
compress({
@@ -96,12 +87,12 @@ describe('Compress Middleware', () => {
9687
}),
9788
],
9889
async () => {
99-
return { test: 'x'.repeat(2000) };
90+
return body;
10091
}
10192
);
10293

10394
// Act
104-
const result = await app.resolve(event, context);
95+
const result = await application.resolve(event, context);
10596

10697
// Assess
10798
expect(result.headers?.['content-encoding']).toEqual('gzip');
@@ -128,9 +119,8 @@ describe('Compress Middleware', () => {
128119
'skips compression for non-compressible content types',
129120
async (contentType) => {
130121
// Prepare
131-
const event = createTestEvent('/test', 'GET');
132-
const app = new Router();
133-
app.get(
122+
const application = new Router();
123+
application.get(
134124
'/test',
135125
[
136126
compress(),
@@ -140,12 +130,12 @@ describe('Compress Middleware', () => {
140130
}),
141131
],
142132
async () => {
143-
return { test: 'x'.repeat(2000) };
133+
return body;
144134
}
145135
);
146136

147137
// Act
148-
const result = await app.resolve(event, context);
138+
const result = await application.resolve(event, context);
149139

150140
// Assess
151141
expect(result.headers?.['content-encoding']).toBeUndefined();
@@ -154,9 +144,8 @@ describe('Compress Middleware', () => {
154144

155145
it('skips compression when cache-control no-transform is set', async () => {
156146
// Prepare
157-
const event = createTestEvent('/test', 'GET');
158-
const app = new Router();
159-
app.get(
147+
const application = new Router();
148+
application.get(
160149
'/test',
161150
[
162151
compress(),
@@ -166,22 +155,21 @@ describe('Compress Middleware', () => {
166155
}),
167156
],
168157
async () => {
169-
return { test: 'x'.repeat(2000) };
158+
return body;
170159
}
171160
);
172161

173162
// Act
174-
const result = await app.resolve(event, context);
163+
const result = await application.resolve(event, context);
175164

176165
// Assess
177166
expect(result.headers?.['content-encoding']).toBeUndefined();
178167
});
179168

180169
it('uses specified encoding when provided', async () => {
181170
// Prepare
182-
const event = createTestEvent('/test', 'GET');
183-
const app = new Router();
184-
app.get(
171+
const application = new Router();
172+
application.get(
185173
'/test',
186174
[
187175
compress({
@@ -192,38 +180,28 @@ describe('Compress Middleware', () => {
192180
}),
193181
],
194182
async () => {
195-
return { test: 'x'.repeat(2000) };
183+
return body;
196184
}
197185
);
198186

199187
// Act
200-
const result = await app.resolve(event, context);
188+
const result = await application.resolve(event, context);
201189

202190
// Assess
203191
expect(result.headers?.['content-encoding']).toBe('deflate');
204192
});
205193

206194
it('infers encoding from Accept-Encoding header', async () => {
207195
// Prepare
208-
const event = createTestEvent('/test', 'GET', {
196+
const deflateCompressionEvent = createTestEvent('/test', 'GET', {
209197
'Accept-Encoding': 'deflate',
210198
});
211-
const app = new Router();
212-
app.get(
213-
'/test',
214-
[
215-
compress(),
216-
createSettingHeadersMiddleware({
217-
'content-length': '2000',
218-
}),
219-
],
220-
async () => {
221-
return { test: 'x'.repeat(2000) };
222-
}
223-
);
199+
app.get('/test', async () => {
200+
return body;
201+
});
224202

225203
// Act
226-
const result = await app.resolve(event, context);
204+
const result = await app.resolve(deflateCompressionEvent, context);
227205

228206
// Assess
229207
expect(result.headers?.['content-encoding']).toBe('deflate');

0 commit comments

Comments
 (0)