main.js 2.1 KB

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