pipework 0.153.0 → 0.155.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/REFERENCE.md +3 -1
- package/dist/REFERENCE.md +322 -13
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/request/di/builder.d.ts +21 -5
- package/dist/request/di/builder.d.ts.map +1 -1
- package/dist/request/di/builder.js +7 -5
- package/dist/request/di/builder.js.map +1 -1
- package/dist/request/di/types.d.ts +45 -6
- package/dist/request/di/types.d.ts.map +1 -1
- package/dist/request/http/server.d.ts.map +1 -1
- package/dist/request/http/server.js +42 -8
- package/dist/request/http/server.js.map +1 -1
- package/dist/request/http/sniff.d.ts +21 -0
- package/dist/request/http/sniff.d.ts.map +1 -0
- package/dist/request/http/sniff.js +145 -0
- package/dist/request/http/sniff.js.map +1 -0
- package/dist/request/http/upload.d.ts +21 -13
- package/dist/request/http/upload.d.ts.map +1 -1
- package/dist/request/http/upload.js +128 -40
- package/dist/request/http/upload.js.map +1 -1
- package/package.json +1 -1
- package/dist/infra/email/sigv4.d.ts +0 -24
- package/dist/infra/email/sigv4.d.ts.map +0 -1
- package/dist/infra/email/sigv4.js +0 -55
- package/dist/infra/email/sigv4.js.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/** Bytes of a file that decide its type. */
|
|
2
|
+
export const SNIFF_BYTES = 512;
|
|
3
|
+
const ZIP = 'application/zip';
|
|
4
|
+
const CFB = 'application/x-cfb';
|
|
5
|
+
const ZIP_REFINEMENTS = [
|
|
6
|
+
'application/vnd.openxmlformats-officedocument.',
|
|
7
|
+
'application/vnd.oasis.opendocument.',
|
|
8
|
+
'application/epub+zip',
|
|
9
|
+
'application/java-archive',
|
|
10
|
+
'application/vnd.android.package-archive',
|
|
11
|
+
];
|
|
12
|
+
const CFB_REFINEMENTS = [
|
|
13
|
+
'application/msword',
|
|
14
|
+
'application/vnd.ms-excel',
|
|
15
|
+
'application/vnd.ms-powerpoint',
|
|
16
|
+
'application/vnd.ms-outlook',
|
|
17
|
+
'application/x-msi',
|
|
18
|
+
];
|
|
19
|
+
const ZIP_EXTENSIONS = {
|
|
20
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
21
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
22
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
23
|
+
odt: 'application/vnd.oasis.opendocument.text',
|
|
24
|
+
ods: 'application/vnd.oasis.opendocument.spreadsheet',
|
|
25
|
+
odp: 'application/vnd.oasis.opendocument.presentation',
|
|
26
|
+
epub: 'application/epub+zip',
|
|
27
|
+
jar: 'application/java-archive',
|
|
28
|
+
apk: 'application/vnd.android.package-archive',
|
|
29
|
+
};
|
|
30
|
+
const CFB_EXTENSIONS = {
|
|
31
|
+
doc: 'application/msword',
|
|
32
|
+
xls: 'application/vnd.ms-excel',
|
|
33
|
+
ppt: 'application/vnd.ms-powerpoint',
|
|
34
|
+
msg: 'application/vnd.ms-outlook',
|
|
35
|
+
msi: 'application/x-msi',
|
|
36
|
+
};
|
|
37
|
+
const ascii = (s) => [...s].map((c) => c.charCodeAt(0));
|
|
38
|
+
const SIGNATURES = [
|
|
39
|
+
{ bytes: ascii('%PDF-'), type: 'application/pdf' },
|
|
40
|
+
{ bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], type: 'image/png' },
|
|
41
|
+
{ bytes: [0xff, 0xd8, 0xff], type: 'image/jpeg' },
|
|
42
|
+
{ bytes: ascii('GIF87a'), type: 'image/gif' },
|
|
43
|
+
{ bytes: ascii('GIF89a'), type: 'image/gif' },
|
|
44
|
+
{ bytes: [0x49, 0x49, 0x2a, 0x00], type: 'image/tiff' },
|
|
45
|
+
{ bytes: [0x4d, 0x4d, 0x00, 0x2a], type: 'image/tiff' },
|
|
46
|
+
{ bytes: [0x00, 0x00, 0x01, 0x00], type: 'image/x-icon' },
|
|
47
|
+
{ bytes: [0x1a, 0x45, 0xdf, 0xa3], type: 'video/x-matroska' }, // webm refined below
|
|
48
|
+
{ bytes: ascii('OggS'), type: 'audio/ogg' },
|
|
49
|
+
{ bytes: ascii('ID3'), type: 'audio/mpeg' },
|
|
50
|
+
{ bytes: ascii('fLaC'), type: 'audio/flac' },
|
|
51
|
+
{ bytes: [0x50, 0x4b, 0x03, 0x04], type: ZIP },
|
|
52
|
+
{ bytes: [0x50, 0x4b, 0x05, 0x06], type: ZIP },
|
|
53
|
+
{ bytes: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1], type: CFB },
|
|
54
|
+
{ bytes: [0x1f, 0x8b], type: 'application/gzip' },
|
|
55
|
+
{ bytes: [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c], type: 'application/x-7z-compressed' },
|
|
56
|
+
{ bytes: [...ascii('Rar!'), 0x1a, 0x07], type: 'application/vnd.rar' },
|
|
57
|
+
{ bytes: ascii('%!PS'), type: 'application/postscript' },
|
|
58
|
+
{ bytes: ascii('{\\rtf'), type: 'application/rtf' },
|
|
59
|
+
{ bytes: ascii('8BPS'), type: 'image/vnd.adobe.photoshop' },
|
|
60
|
+
];
|
|
61
|
+
const FTYP_BRANDS = {
|
|
62
|
+
heic: 'image/heic', heix: 'image/heic', hevc: 'image/heic', hevx: 'image/heic', heim: 'image/heic', heis: 'image/heic',
|
|
63
|
+
mif1: 'image/heif', msf1: 'image/heif',
|
|
64
|
+
avif: 'image/avif', avis: 'image/avif',
|
|
65
|
+
'M4A ': 'audio/mp4',
|
|
66
|
+
'qt ': 'video/quicktime',
|
|
67
|
+
};
|
|
68
|
+
const RIFF_FORMS = {
|
|
69
|
+
WEBP: 'image/webp',
|
|
70
|
+
WAVE: 'audio/wav',
|
|
71
|
+
'AVI ': 'video/x-msvideo',
|
|
72
|
+
};
|
|
73
|
+
/** Types whose files always show their signature. MP3 is left out: a file without an ID3 tag has none we detect. */
|
|
74
|
+
export const sniffable = new Set([
|
|
75
|
+
...SIGNATURES.map((s) => s.type).filter((t) => t !== 'audio/mpeg'),
|
|
76
|
+
'image/bmp',
|
|
77
|
+
'video/webm',
|
|
78
|
+
...Object.values(RIFF_FORMS),
|
|
79
|
+
...Object.values(FTYP_BRANDS),
|
|
80
|
+
'video/3gpp',
|
|
81
|
+
'video/mp4',
|
|
82
|
+
]);
|
|
83
|
+
function matches(head, sig) {
|
|
84
|
+
const offset = sig.offset ?? 0;
|
|
85
|
+
if (head.length < offset + sig.bytes.length)
|
|
86
|
+
return false;
|
|
87
|
+
return sig.bytes.every((b, i) => head[offset + i] === b);
|
|
88
|
+
}
|
|
89
|
+
/** The media type the first bytes of a file say it is, or null when no signature matches. */
|
|
90
|
+
export function detectMediaType(head) {
|
|
91
|
+
const h = head.length > SNIFF_BYTES ? head.subarray(0, SNIFF_BYTES) : head;
|
|
92
|
+
if (h.length >= 12 && h.toString('latin1', 0, 4) === 'RIFF') {
|
|
93
|
+
const form = RIFF_FORMS[h.toString('latin1', 8, 12)];
|
|
94
|
+
if (form !== undefined)
|
|
95
|
+
return form;
|
|
96
|
+
}
|
|
97
|
+
if (h.length >= 12 && h.toString('latin1', 4, 8) === 'ftyp') {
|
|
98
|
+
const brand = h.toString('latin1', 8, 12);
|
|
99
|
+
const known = FTYP_BRANDS[brand];
|
|
100
|
+
if (known !== undefined)
|
|
101
|
+
return known;
|
|
102
|
+
return brand.startsWith('3gp') ? 'video/3gpp' : 'video/mp4';
|
|
103
|
+
}
|
|
104
|
+
// BM, reserved zeros at 6-9, and a known DIB header size at 14: 'BM' alone is common text.
|
|
105
|
+
if (h.length >= 18 && h.toString('latin1', 0, 2) === 'BM' && h.readUInt32LE(6) === 0 && [12, 40, 52, 56, 64, 108, 124].includes(h.readUInt32LE(14)))
|
|
106
|
+
return 'image/bmp';
|
|
107
|
+
for (const sig of SIGNATURES) {
|
|
108
|
+
if (!matches(h, sig))
|
|
109
|
+
continue;
|
|
110
|
+
if (sig.type === 'video/x-matroska')
|
|
111
|
+
return h.includes('webm', 4, 'latin1') ? 'video/webm' : sig.type;
|
|
112
|
+
return sig.type;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
function refinedBy(refinements, declared) {
|
|
117
|
+
return refinements.some((r) => (r.endsWith('.') ? declared.startsWith(r) : declared === r));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The type a file is treated as: what its bytes say, unless the bytes name a
|
|
121
|
+
* container (zip, compound file) that the declared type or the filename
|
|
122
|
+
* extension narrows. `mediaType` is '' (matches nothing) when the declared type
|
|
123
|
+
* is one a signature would show and the bytes do not show it.
|
|
124
|
+
*/
|
|
125
|
+
export function resolveMediaType(input) {
|
|
126
|
+
const { head, declared, extension } = input;
|
|
127
|
+
const detectedType = detectMediaType(head);
|
|
128
|
+
const containers = [
|
|
129
|
+
[ZIP, ZIP_REFINEMENTS, ZIP_EXTENSIONS],
|
|
130
|
+
[CFB, CFB_REFINEMENTS, CFB_EXTENSIONS],
|
|
131
|
+
];
|
|
132
|
+
for (const [type, refinements, extensions] of containers) {
|
|
133
|
+
if (detectedType !== type)
|
|
134
|
+
continue;
|
|
135
|
+
if (refinedBy(refinements, declared))
|
|
136
|
+
return { detectedType, mediaType: declared };
|
|
137
|
+
const byExtension = extension === null ? undefined : extensions[extension];
|
|
138
|
+
if (byExtension !== undefined)
|
|
139
|
+
return { detectedType, mediaType: byExtension };
|
|
140
|
+
}
|
|
141
|
+
if (detectedType !== null)
|
|
142
|
+
return { detectedType, mediaType: detectedType };
|
|
143
|
+
return { detectedType, mediaType: sniffable.has(declared) ? '' : declared };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=sniff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sniff.js","sourceRoot":"","sources":["../../../src/request/http/sniff.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,28 +8,36 @@ export declare const MULTIPART_FIELD_LIMIT: number;
|
|
|
8
8
|
export declare function uploadBodyLimit(config: UploadConfig): number;
|
|
9
9
|
/** `type/subtype` of a Content-Type value, lowercased and without parameters. */
|
|
10
10
|
export declare function mediaTypeOf(value: string | undefined): string;
|
|
11
|
-
/** True when `mediaType` matches an allowed entry
|
|
11
|
+
/** True when `mediaType` matches an allowed entry: exactly, by `type/*`, or by a star on each side of the slash (any non-empty type). */
|
|
12
12
|
export declare function mediaTypeAllowed(allowed: readonly string[], mediaType: string): boolean;
|
|
13
|
+
/** True for a 413 or 415 pipework raised for a file, as opposed to one a handler threw. */
|
|
14
|
+
export declare function isUploadRefusal(error: unknown): error is PayloadTooLargeError | UnsupportedMediaTypeError;
|
|
15
|
+
/** What pipework knows of the file at the moment it refuses it. */
|
|
16
|
+
export interface UploadTrack {
|
|
17
|
+
declaredType: string;
|
|
18
|
+
extension: string | null;
|
|
19
|
+
filename: string | null;
|
|
20
|
+
detectedType: string | null;
|
|
21
|
+
bytesRead: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function newUploadTrack(): UploadTrack;
|
|
13
24
|
/**
|
|
14
|
-
* Refuses
|
|
15
|
-
*
|
|
16
|
-
*
|
|
25
|
+
* Refuses a multipart route's request that is not `multipart/form-data`, from
|
|
26
|
+
* its headers alone. A protocol error: no file is involved. Binary routes have
|
|
27
|
+
* no header check; their type is settled from the bytes.
|
|
17
28
|
*/
|
|
18
|
-
export declare function checkUploadHeaders(config: UploadConfig, headers: Record<string, string | string[] | undefined>): UnsupportedMediaTypeError |
|
|
29
|
+
export declare function checkUploadHeaders(config: UploadConfig, headers: Record<string, string | string[] | undefined>): UnsupportedMediaTypeError | null;
|
|
19
30
|
/**
|
|
20
31
|
* Passes `source` through, erroring with a 413 once more than `maxBytes` have
|
|
21
32
|
* passed. A failure of `source` becomes the failure of the returned stream.
|
|
22
33
|
*/
|
|
23
|
-
export declare function limitStream(source: Readable, maxBytes: number, mapError?: (e: unknown) => Error, onUnfinished?: () => Error): Readable;
|
|
24
|
-
/** Starts a binary upload: the request payload as a size-limited stream. */
|
|
25
|
-
export declare function binaryUpload(req: FastifyRequest, maxBytes: number): BinaryUpload;
|
|
34
|
+
export declare function limitStream(source: Readable, maxBytes: number, mapError?: (e: unknown) => Error, onUnfinished?: () => Error, track?: UploadTrack): Readable;
|
|
26
35
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
36
|
+
* Starts an upload: refuses a declared length over the limit, builds the size-
|
|
37
|
+
* limited file stream, reads its first bytes to settle the media type, and
|
|
38
|
+
* refuses a type outside the route's list. `track` follows what is learned.
|
|
29
39
|
*/
|
|
30
|
-
export declare function
|
|
31
|
-
kind: 'multipart';
|
|
32
|
-
}>): Promise<MultipartUpload>;
|
|
40
|
+
export declare function startUpload(req: FastifyRequest, config: UploadConfig, track: UploadTrack): Promise<BinaryUpload | MultipartUpload>;
|
|
33
41
|
/**
|
|
34
42
|
* Ends an upload after its handler: a stream not read to the end is destroyed.
|
|
35
43
|
* Returns true when the body was left incomplete, so the caller closes the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/request/http/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/request/http/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEjF,OAAO,EAA4C,oBAAoB,EAAE,yBAAyB,EAAmB,MAAM,4BAA4B,CAAA;AAEvJ,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,QAAY,CAAA;AAG9C,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAG5D;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG7D;AAED,yIAAyI;AACzI,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAQvF;AASD,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,GAAG,yBAAyB,CAEzG;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,yBAAyB,GAAG,IAAI,CAWjJ;AAWD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,QAAQ,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,CAAC,CAAC,EAAE,OAAO,KAAK,KAAyB,EACnD,YAAY,CAAC,EAAE,MAAM,KAAK,EAC1B,KAAK,CAAC,EAAE,WAAW,GAClB,QAAQ,CA0BV;AA4FD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,GAAG,eAAe,CAAC,CAmBxI;AAyCD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAMlE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Readable, Transform } from 'node:stream';
|
|
2
|
+
import { resolveMediaType, SNIFF_BYTES } from './sniff.js';
|
|
2
3
|
import { isPipeworkError, MalformedMultipartError, PayloadTooLargeError, UnsupportedMediaTypeError, ValidationError } from '../../core/errors/index.js';
|
|
3
4
|
/** Largest accepted multipart text field, in bytes. */
|
|
4
5
|
export const MULTIPART_FIELD_LIMIT = 64 * 1024;
|
|
@@ -15,36 +16,52 @@ export function mediaTypeOf(value) {
|
|
|
15
16
|
return '';
|
|
16
17
|
return (value.split(';')[0] ?? '').trim().toLowerCase();
|
|
17
18
|
}
|
|
18
|
-
/** True when `mediaType` matches an allowed entry
|
|
19
|
+
/** True when `mediaType` matches an allowed entry: exactly, by `type/*`, or by a star on each side of the slash (any non-empty type). */
|
|
19
20
|
export function mediaTypeAllowed(allowed, mediaType) {
|
|
20
21
|
if (mediaType === '')
|
|
21
22
|
return false;
|
|
22
23
|
for (const entry of allowed) {
|
|
23
24
|
const a = entry.trim().toLowerCase();
|
|
24
|
-
if (a === mediaType)
|
|
25
|
+
if (a === mediaType || a === '*/*')
|
|
25
26
|
return true;
|
|
26
27
|
if (a.endsWith('/*') && mediaType.startsWith(a.slice(0, -1)))
|
|
27
28
|
return true;
|
|
28
29
|
}
|
|
29
30
|
return false;
|
|
30
31
|
}
|
|
32
|
+
const pipeworkRefusals = new WeakSet();
|
|
33
|
+
function refusal(error) {
|
|
34
|
+
pipeworkRefusals.add(error);
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
37
|
+
/** True for a 413 or 415 pipework raised for a file, as opposed to one a handler threw. */
|
|
38
|
+
export function isUploadRefusal(error) {
|
|
39
|
+
return typeof error === 'object' && error !== null && pipeworkRefusals.has(error);
|
|
40
|
+
}
|
|
41
|
+
export function newUploadTrack() {
|
|
42
|
+
return { declaredType: '', extension: null, filename: null, detectedType: null, bytesRead: 0 };
|
|
43
|
+
}
|
|
31
44
|
/**
|
|
32
|
-
* Refuses
|
|
33
|
-
*
|
|
34
|
-
*
|
|
45
|
+
* Refuses a multipart route's request that is not `multipart/form-data`, from
|
|
46
|
+
* its headers alone. A protocol error: no file is involved. Binary routes have
|
|
47
|
+
* no header check; their type is settled from the bytes.
|
|
35
48
|
*/
|
|
36
49
|
export function checkUploadHeaders(config, headers) {
|
|
50
|
+
if (config.kind === 'binary')
|
|
51
|
+
return null;
|
|
37
52
|
const contentType = headers['content-type'];
|
|
38
53
|
const mediaType = mediaTypeOf(Array.isArray(contentType) ? contentType[0] : contentType);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
if (mediaType === 'multipart/form-data')
|
|
55
|
+
return null;
|
|
56
|
+
return new UnsupportedMediaTypeError(mediaType === ''
|
|
57
|
+
? 'This route needs a Content-Type; accepted: multipart/form-data'
|
|
58
|
+
: `Media type ${mediaType} is not accepted; accepted: multipart/form-data`, { accepted: ['multipart/form-data'] });
|
|
59
|
+
}
|
|
60
|
+
/** 413 when the request declares a length over what the route may receive. */
|
|
61
|
+
function checkDeclaredLength(config, headers) {
|
|
45
62
|
const declared = Number(headers['content-length']);
|
|
46
63
|
if (headers['content-length'] !== undefined && Number.isFinite(declared) && declared > uploadBodyLimit(config)) {
|
|
47
|
-
return new PayloadTooLargeError(`Request body is ${declared} bytes; the limit is ${config.maxBytes}`, { maxBytes: config.maxBytes });
|
|
64
|
+
return refusal(new PayloadTooLargeError(`Request body is ${declared} bytes; the limit is ${config.maxBytes}`, { maxBytes: config.maxBytes }));
|
|
48
65
|
}
|
|
49
66
|
return null;
|
|
50
67
|
}
|
|
@@ -52,14 +69,16 @@ export function checkUploadHeaders(config, headers) {
|
|
|
52
69
|
* Passes `source` through, erroring with a 413 once more than `maxBytes` have
|
|
53
70
|
* passed. A failure of `source` becomes the failure of the returned stream.
|
|
54
71
|
*/
|
|
55
|
-
export function limitStream(source, maxBytes, mapError = (e) => e, onUnfinished) {
|
|
72
|
+
export function limitStream(source, maxBytes, mapError = (e) => e, onUnfinished, track) {
|
|
56
73
|
let seen = 0;
|
|
57
74
|
const counter = new Transform({
|
|
58
75
|
transform(chunk, _enc, cb) {
|
|
59
76
|
seen += chunk.length;
|
|
77
|
+
if (track !== undefined)
|
|
78
|
+
track.bytesRead = seen;
|
|
60
79
|
if (seen > maxBytes) {
|
|
61
80
|
source.unpipe(counter);
|
|
62
|
-
cb(new PayloadTooLargeError(`Upload is over the limit of ${maxBytes} bytes`, { maxBytes }));
|
|
81
|
+
cb(refusal(new PayloadTooLargeError(`Upload is over the limit of ${maxBytes} bytes`, { maxBytes })));
|
|
63
82
|
return;
|
|
64
83
|
}
|
|
65
84
|
cb(null, chunk);
|
|
@@ -84,7 +103,7 @@ export function limitStream(source, maxBytes, mapError = (e) => e, onUnfinished)
|
|
|
84
103
|
function toUploadError(e) {
|
|
85
104
|
const code = e?.code;
|
|
86
105
|
if (code === 'FST_REQ_FILE_TOO_LARGE')
|
|
87
|
-
return new PayloadTooLargeError('Uploaded file is over the size limit');
|
|
106
|
+
return refusal(new PayloadTooLargeError('Uploaded file is over the size limit'));
|
|
88
107
|
return asMalformedMultipart(e);
|
|
89
108
|
}
|
|
90
109
|
/** A parser failure becomes a 400; errors that already carry a status are kept. */
|
|
@@ -97,31 +116,101 @@ function asMalformedMultipart(e) {
|
|
|
97
116
|
const message = e instanceof Error ? e.message : String(e);
|
|
98
117
|
return new MalformedMultipartError(undefined, { cause: message });
|
|
99
118
|
}
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
return
|
|
107
|
-
stream: limitStream(source, maxBytes),
|
|
108
|
-
mediaType: mediaTypeOf(req.headers['content-type']),
|
|
109
|
-
length: length !== null && Number.isFinite(length) ? length : null,
|
|
110
|
-
};
|
|
119
|
+
/** Lowercase text after the last dot of a filename; null without a filename or a dot. */
|
|
120
|
+
function extensionOf(filename) {
|
|
121
|
+
if (filename === null)
|
|
122
|
+
return null;
|
|
123
|
+
const dot = filename.lastIndexOf('.');
|
|
124
|
+
const ext = dot < 0 ? '' : filename.slice(dot + 1).toLowerCase();
|
|
125
|
+
return ext === '' ? null : ext;
|
|
111
126
|
}
|
|
112
127
|
/**
|
|
113
|
-
* Reads
|
|
114
|
-
*
|
|
128
|
+
* Reads up to SNIFF_BYTES from `source`, then returns them with a stream that
|
|
129
|
+
* yields them again followed by the rest of `source`, byte for byte. Nothing
|
|
130
|
+
* further is buffered. A failure of `source` while reading the head is thrown.
|
|
131
|
+
*/
|
|
132
|
+
async function withHead(source) {
|
|
133
|
+
const it = source[Symbol.asyncIterator]();
|
|
134
|
+
const chunks = [];
|
|
135
|
+
let length = 0;
|
|
136
|
+
let ended = false;
|
|
137
|
+
while (length < SNIFF_BYTES) {
|
|
138
|
+
const next = await it.next();
|
|
139
|
+
if (next.done === true) {
|
|
140
|
+
ended = true;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
chunks.push(next.value);
|
|
144
|
+
length += next.value.length;
|
|
145
|
+
}
|
|
146
|
+
const all = Buffer.concat(chunks);
|
|
147
|
+
async function* rejoin() {
|
|
148
|
+
try {
|
|
149
|
+
if (all.length > 0)
|
|
150
|
+
yield all;
|
|
151
|
+
while (!ended) {
|
|
152
|
+
const next = await it.next();
|
|
153
|
+
if (next.done === true)
|
|
154
|
+
return;
|
|
155
|
+
yield next.value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
source.destroy();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const stream = Readable.from(rejoin(), { objectMode: false });
|
|
163
|
+
stream.on('close', () => source.destroy());
|
|
164
|
+
return { head: all.subarray(0, SNIFF_BYTES), stream };
|
|
165
|
+
}
|
|
166
|
+
/** Reads the head of `limited`, settles the file's type and refuses a type outside the route's list. */
|
|
167
|
+
async function sniffFile(config, limited, declaredType, filename, track) {
|
|
168
|
+
const extension = extensionOf(filename);
|
|
169
|
+
track.declaredType = declaredType;
|
|
170
|
+
track.filename = filename;
|
|
171
|
+
track.extension = extension;
|
|
172
|
+
const { head, stream } = await withHead(limited);
|
|
173
|
+
const { detectedType, mediaType } = resolveMediaType({ head, declared: declaredType, extension });
|
|
174
|
+
track.detectedType = detectedType;
|
|
175
|
+
if (!mediaTypeAllowed(config.mediaTypes, mediaType)) {
|
|
176
|
+
stream.destroy();
|
|
177
|
+
throw refusal(new UnsupportedMediaTypeError(`File media type is not accepted (detected ${detectedType ?? 'none'}, declared ${declaredType === '' ? 'none' : declaredType}); accepted: ${config.mediaTypes.join(', ')}`, { accepted: config.mediaTypes, detectedType, declaredType }));
|
|
178
|
+
}
|
|
179
|
+
return { stream, mediaType, detectedType, declaredType, extension };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Starts an upload: refuses a declared length over the limit, builds the size-
|
|
183
|
+
* limited file stream, reads its first bytes to settle the media type, and
|
|
184
|
+
* refuses a type outside the route's list. `track` follows what is learned.
|
|
115
185
|
*/
|
|
116
|
-
export async function
|
|
186
|
+
export async function startUpload(req, config, track) {
|
|
187
|
+
if (config.kind === 'binary') {
|
|
188
|
+
track.declaredType = mediaTypeOf(req.headers['content-type']);
|
|
189
|
+
const tooLarge = checkDeclaredLength(config, req.headers);
|
|
190
|
+
if (tooLarge !== null)
|
|
191
|
+
throw tooLarge;
|
|
192
|
+
const body = req.body;
|
|
193
|
+
const source = body instanceof Readable ? body : Readable.from([]);
|
|
194
|
+
const declared = req.headers['content-length'];
|
|
195
|
+
const length = declared === undefined ? null : Number(declared);
|
|
196
|
+
const file = await sniffFile(config, limitStream(source, config.maxBytes, undefined, undefined, track), track.declaredType, null, track);
|
|
197
|
+
return { ...file, length: length !== null && Number.isFinite(length) ? length : null };
|
|
198
|
+
}
|
|
199
|
+
const tooLarge = checkDeclaredLength(config, req.headers);
|
|
200
|
+
if (tooLarge !== null)
|
|
201
|
+
throw tooLarge;
|
|
117
202
|
try {
|
|
118
|
-
return await readMultipart(req, config);
|
|
203
|
+
return await readMultipart(req, config, track);
|
|
119
204
|
}
|
|
120
205
|
catch (e) {
|
|
121
206
|
throw asMalformedMultipart(e);
|
|
122
207
|
}
|
|
123
208
|
}
|
|
124
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Reads a multipart body up to its file part: the text fields before it, then
|
|
211
|
+
* the file as a size-limited stream. Nothing after the file part is read.
|
|
212
|
+
*/
|
|
213
|
+
async function readMultipart(req, config, track) {
|
|
125
214
|
const allowedFields = new Set(config.fields ?? []);
|
|
126
215
|
const fields = {};
|
|
127
216
|
for await (const part of req.parts()) {
|
|
@@ -139,17 +228,16 @@ async function readMultipart(req, config) {
|
|
|
139
228
|
part.file.resume();
|
|
140
229
|
throw new ValidationError({ [part.fieldname]: ['Unexpected file field'] }, `Unexpected file field "${part.fieldname}"; the file goes in "${config.file}"`);
|
|
141
230
|
}
|
|
142
|
-
const
|
|
143
|
-
|
|
231
|
+
const filename = part.filename === '' ? null : part.filename;
|
|
232
|
+
const limited = limitStream(part.file, config.maxBytes, toUploadError, () => new MalformedMultipartError(undefined, { cause: 'The body ended before the file part was closed' }), track);
|
|
233
|
+
try {
|
|
234
|
+
const file = await sniffFile(config, limited, mediaTypeOf(part.mimetype), filename, track);
|
|
235
|
+
return { ...file, filename, fields };
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
144
238
|
part.file.resume();
|
|
145
|
-
throw
|
|
239
|
+
throw e;
|
|
146
240
|
}
|
|
147
|
-
return {
|
|
148
|
-
stream: limitStream(part.file, config.maxBytes, toUploadError, () => new MalformedMultipartError(undefined, { cause: 'The body ended before the file part was closed' })),
|
|
149
|
-
mediaType,
|
|
150
|
-
filename: part.filename === '' ? null : part.filename,
|
|
151
|
-
fields,
|
|
152
|
-
};
|
|
153
241
|
}
|
|
154
242
|
throw new ValidationError({ [config.file]: ['Required'] }, `The form has no file part named "${config.file}"`);
|
|
155
243
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/request/http/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAEvJ,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,CAAA;AAC9C,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAA;AAEpC,yFAAyF;AACzF,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAA;IACpD,OAAO,MAAM,CAAC,QAAQ,GAAG,kBAAkB,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,qBAAqB,CAAA;AACpG,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AACzD,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/request/http/upload.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export interface AwsCredentials {
|
|
2
|
-
readonly accessKeyId: string;
|
|
3
|
-
readonly secretAccessKey: string;
|
|
4
|
-
readonly sessionToken?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface SigV4Request {
|
|
7
|
-
readonly method: string;
|
|
8
|
-
readonly url: string;
|
|
9
|
-
/** Headers to sign and send, other than host and x-amz-date, which are added. */
|
|
10
|
-
readonly headers: Readonly<Record<string, string>>;
|
|
11
|
-
readonly body: string | Buffer;
|
|
12
|
-
readonly region: string;
|
|
13
|
-
readonly service: string;
|
|
14
|
-
readonly credentials: AwsCredentials;
|
|
15
|
-
readonly now?: Date;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Signs a request with AWS Signature Version 4 and returns the headers to send:
|
|
19
|
-
* the given ones, `x-amz-date`, `x-amz-security-token` when the credentials carry
|
|
20
|
-
* a session token, and `authorization`. `host` is signed but not returned; the
|
|
21
|
-
* HTTP client sets it from the URL.
|
|
22
|
-
*/
|
|
23
|
-
export declare function signV4(req: SigV4Request): Record<string, string>;
|
|
24
|
-
//# sourceMappingURL=sigv4.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sigv4.d.ts","sourceRoot":"","sources":["../../../src/infra/email/sigv4.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CACpB;AAkBD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwChE"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { createHash, createHmac } from 'node:crypto';
|
|
2
|
-
function sha256Hex(data) {
|
|
3
|
-
return createHash('sha256').update(data).digest('hex');
|
|
4
|
-
}
|
|
5
|
-
function hmac(key, data) {
|
|
6
|
-
return createHmac('sha256', key).update(data).digest();
|
|
7
|
-
}
|
|
8
|
-
function uriEncode(s) {
|
|
9
|
-
return encodeURIComponent(s).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
10
|
-
}
|
|
11
|
-
function amzDate(d) {
|
|
12
|
-
return d.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Signs a request with AWS Signature Version 4 and returns the headers to send:
|
|
16
|
-
* the given ones, `x-amz-date`, `x-amz-security-token` when the credentials carry
|
|
17
|
-
* a session token, and `authorization`. `host` is signed but not returned; the
|
|
18
|
-
* HTTP client sets it from the URL.
|
|
19
|
-
*/
|
|
20
|
-
export function signV4(req) {
|
|
21
|
-
const url = new URL(req.url);
|
|
22
|
-
const stamp = amzDate(req.now ?? new Date());
|
|
23
|
-
const day = stamp.slice(0, 8);
|
|
24
|
-
const headers = {};
|
|
25
|
-
for (const [name, value] of Object.entries(req.headers))
|
|
26
|
-
headers[name.toLowerCase()] = value.trim().replace(/\s+/g, ' ');
|
|
27
|
-
headers['x-amz-date'] = stamp;
|
|
28
|
-
if (req.credentials.sessionToken !== undefined)
|
|
29
|
-
headers['x-amz-security-token'] = req.credentials.sessionToken;
|
|
30
|
-
const signed = { ...headers, host: url.host };
|
|
31
|
-
const names = Object.keys(signed).sort();
|
|
32
|
-
const canonicalHeaders = names.map(n => `${n}:${signed[n]}\n`).join('');
|
|
33
|
-
const signedHeaders = names.join(';');
|
|
34
|
-
const canonicalPath = url.pathname.split('/').map(uriEncode).join('/');
|
|
35
|
-
const canonicalQuery = [...url.searchParams.entries()]
|
|
36
|
-
.map(([k, v]) => [uriEncode(k), uriEncode(v)])
|
|
37
|
-
.sort((a, b) => (a[0] === b[0] ? (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0) : (a[0] < b[0] ? -1 : 1)))
|
|
38
|
-
.map(([k, v]) => `${k}=${v}`)
|
|
39
|
-
.join('&');
|
|
40
|
-
const canonicalRequest = [
|
|
41
|
-
req.method.toUpperCase(), canonicalPath, canonicalQuery, canonicalHeaders, signedHeaders, sha256Hex(req.body),
|
|
42
|
-
].join('\n');
|
|
43
|
-
const scope = `${day}/${req.region}/${req.service}/aws4_request`;
|
|
44
|
-
const stringToSign = ['AWS4-HMAC-SHA256', stamp, scope, sha256Hex(canonicalRequest)].join('\n');
|
|
45
|
-
const kDate = hmac(`AWS4${req.credentials.secretAccessKey}`, day);
|
|
46
|
-
const kRegion = hmac(kDate, req.region);
|
|
47
|
-
const kService = hmac(kRegion, req.service);
|
|
48
|
-
const kSigning = hmac(kService, 'aws4_request');
|
|
49
|
-
const signature = createHmac('sha256', kSigning).update(stringToSign).digest('hex');
|
|
50
|
-
return {
|
|
51
|
-
...headers,
|
|
52
|
-
authorization: `AWS4-HMAC-SHA256 Credential=${req.credentials.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=sigv4.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sigv4.js","sourceRoot":"","sources":["../../../src/infra/email/sigv4.ts"],"names":[],"mappings":"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"}
|