You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.3 KiB

  1. var fs = require('fs'),
  2. WritableStream = require('stream').Writable,
  3. inherits = require('util').inherits;
  4. var parseParams = require('./utils').parseParams;
  5. function Busboy(opts) {
  6. if (!(this instanceof Busboy))
  7. return new Busboy(opts);
  8. if (opts.highWaterMark !== undefined)
  9. WritableStream.call(this, { highWaterMark: opts.highWaterMark });
  10. else
  11. WritableStream.call(this);
  12. this._done = false;
  13. this._parser = undefined;
  14. this._finished = false;
  15. this.opts = opts;
  16. if (opts.headers && typeof opts.headers['content-type'] === 'string')
  17. this.parseHeaders(opts.headers);
  18. else
  19. throw new Error('Missing Content-Type');
  20. }
  21. inherits(Busboy, WritableStream);
  22. Busboy.prototype.emit = function(ev) {
  23. if (ev === 'finish') {
  24. if (!this._done) {
  25. this._parser && this._parser.end();
  26. return;
  27. } else if (this._finished) {
  28. return;
  29. }
  30. this._finished = true;
  31. }
  32. WritableStream.prototype.emit.apply(this, arguments);
  33. };
  34. Busboy.prototype.parseHeaders = function(headers) {
  35. this._parser = undefined;
  36. if (headers['content-type']) {
  37. var parsed = parseParams(headers['content-type']),
  38. matched, type;
  39. for (var i = 0; i < TYPES.length; ++i) {
  40. type = TYPES[i];
  41. if (typeof type.detect === 'function')
  42. matched = type.detect(parsed);
  43. else
  44. matched = type.detect.test(parsed[0]);
  45. if (matched)
  46. break;
  47. }
  48. if (matched) {
  49. var cfg = {
  50. limits: this.opts.limits,
  51. headers: headers,
  52. parsedConType: parsed,
  53. highWaterMark: undefined,
  54. fileHwm: undefined,
  55. defCharset: undefined,
  56. preservePath: false
  57. };
  58. if (this.opts.highWaterMark)
  59. cfg.highWaterMark = this.opts.highWaterMark;
  60. if (this.opts.fileHwm)
  61. cfg.fileHwm = this.opts.fileHwm;
  62. cfg.defCharset = this.opts.defCharset;
  63. cfg.preservePath = this.opts.preservePath;
  64. this._parser = type(this, cfg);
  65. return;
  66. }
  67. }
  68. throw new Error('Unsupported content type: ' + headers['content-type']);
  69. };
  70. Busboy.prototype._write = function(chunk, encoding, cb) {
  71. if (!this._parser)
  72. return cb(new Error('Not ready to parse. Missing Content-Type?'));
  73. this._parser.write(chunk, cb);
  74. };
  75. var TYPES = [
  76. require('./types/multipart'),
  77. require('./types/urlencoded'),
  78. ];
  79. module.exports = Busboy;