-
Notifications
You must be signed in to change notification settings - Fork 18
/
index.ts
88 lines (76 loc) · 1.91 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* @packageDocumentation
*
* Allows iterating over multipart messages found in a HTTP request/
*
* @example
*
* ```javascript
* import http from 'http'
* import multipart from 'it-multipart'
*
* http.createServer(async (req, res) => {
* if (req.method === 'POST' && req.headers['content-type']) {
* for await (const part of multipart(req)) {
* console.log(`part with HTTP headers ${part.headers}`)
*
* // nb. part.body must be consumed before the next part is emitted
* for await (const chunk of part.body) {
* console.log(`part with content ${part.name} contents:`, chunk.toString())
* }
* }
*
* console.log('finished parsing')
* res.writeHead(200)
* res.end()
* }
*
* res.writeHead(404)
* res.end()
* }).listen(5001, () => {
* console.log('server listening on port 5001')
* })
* ```
*/
import formidable from 'formidable'
import { pushable } from 'it-pushable'
import type { IncomingMessage, IncomingHttpHeaders } from 'http'
export interface Part {
headers: IncomingHttpHeaders
body: AsyncIterable<Uint8Array>
}
/**
* Streaming multipart HTTP message parser
*/
export default async function * multipart (request: IncomingMessage): AsyncGenerator<Part, void, undefined> {
const output = pushable<Part>({
objectMode: true
})
if (request == null) {
output.end(new Error('request missing'))
yield * output
return
}
const form = formidable({ keepExtensions: true })
form.parse(request, err => {
output.end(err)
})
form.onPart = (part) => {
const body = pushable()
part.on('data', buf => {
body.push(buf)
})
part.on('end', () => {
body.end()
})
part.on('error', (err) => {
body.end(err)
})
output.push({
// @ts-expect-error headers is not part of formidable api but is present
headers: part.headers,
body
})
}
yield * output
}