main.js 2.4 KB

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