[d24f17c] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | const WritableStream = require('node:stream').Writable
|
---|
| 4 | const { inherits } = require('node:util')
|
---|
| 5 | const Dicer = require('../deps/dicer/lib/Dicer')
|
---|
| 6 |
|
---|
| 7 | const MultipartParser = require('./types/multipart')
|
---|
| 8 | const UrlencodedParser = require('./types/urlencoded')
|
---|
| 9 | const parseParams = require('./utils/parseParams')
|
---|
| 10 |
|
---|
| 11 | function Busboy (opts) {
|
---|
| 12 | if (!(this instanceof Busboy)) { return new Busboy(opts) }
|
---|
| 13 |
|
---|
| 14 | if (typeof opts !== 'object') {
|
---|
| 15 | throw new TypeError('Busboy expected an options-Object.')
|
---|
| 16 | }
|
---|
| 17 | if (typeof opts.headers !== 'object') {
|
---|
| 18 | throw new TypeError('Busboy expected an options-Object with headers-attribute.')
|
---|
| 19 | }
|
---|
| 20 | if (typeof opts.headers['content-type'] !== 'string') {
|
---|
| 21 | throw new TypeError('Missing Content-Type-header.')
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | const {
|
---|
| 25 | headers,
|
---|
| 26 | ...streamOptions
|
---|
| 27 | } = opts
|
---|
| 28 |
|
---|
| 29 | this.opts = {
|
---|
| 30 | autoDestroy: false,
|
---|
| 31 | ...streamOptions
|
---|
| 32 | }
|
---|
| 33 | WritableStream.call(this, this.opts)
|
---|
| 34 |
|
---|
| 35 | this._done = false
|
---|
| 36 | this._parser = this.getParserByHeaders(headers)
|
---|
| 37 | this._finished = false
|
---|
| 38 | }
|
---|
| 39 | inherits(Busboy, WritableStream)
|
---|
| 40 |
|
---|
| 41 | Busboy.prototype.emit = function (ev) {
|
---|
| 42 | if (ev === 'finish') {
|
---|
| 43 | if (!this._done) {
|
---|
| 44 | this._parser?.end()
|
---|
| 45 | return
|
---|
| 46 | } else if (this._finished) {
|
---|
| 47 | return
|
---|
| 48 | }
|
---|
| 49 | this._finished = true
|
---|
| 50 | }
|
---|
| 51 | WritableStream.prototype.emit.apply(this, arguments)
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | Busboy.prototype.getParserByHeaders = function (headers) {
|
---|
| 55 | const parsed = parseParams(headers['content-type'])
|
---|
| 56 |
|
---|
| 57 | const cfg = {
|
---|
| 58 | defCharset: this.opts.defCharset,
|
---|
| 59 | fileHwm: this.opts.fileHwm,
|
---|
| 60 | headers,
|
---|
| 61 | highWaterMark: this.opts.highWaterMark,
|
---|
| 62 | isPartAFile: this.opts.isPartAFile,
|
---|
| 63 | limits: this.opts.limits,
|
---|
| 64 | parsedConType: parsed,
|
---|
| 65 | preservePath: this.opts.preservePath
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | if (MultipartParser.detect.test(parsed[0])) {
|
---|
| 69 | return new MultipartParser(this, cfg)
|
---|
| 70 | }
|
---|
| 71 | if (UrlencodedParser.detect.test(parsed[0])) {
|
---|
| 72 | return new UrlencodedParser(this, cfg)
|
---|
| 73 | }
|
---|
| 74 | throw new Error('Unsupported Content-Type.')
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | Busboy.prototype._write = function (chunk, encoding, cb) {
|
---|
| 78 | this._parser.write(chunk, cb)
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | module.exports = Busboy
|
---|
| 82 | module.exports.default = Busboy
|
---|
| 83 | module.exports.Busboy = Busboy
|
---|
| 84 |
|
---|
| 85 | module.exports.Dicer = Dicer
|
---|