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