Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / connect / lib / middleware / multipart.js
1 /*!
2  * Connect - multipart
3  * Copyright(c) 2010 Sencha Inc.
4  * Copyright(c) 2011 TJ Holowaychuk
5  * MIT Licensed
6  */
7
8 /**
9  * Module dependencies.
10  */
11
12 var deprecate = require('depd')('connect');
13 var multiparty = require('multiparty')
14   , typeis = require('type-is')
15   , _limit = require('./limit')
16   , qs = require('qs');
17
18 /**
19  * Multipart:
20  *
21  * Status: Deprecated. The multipart parser will be removed in Connect 3.0.
22  * Please use one of the following parsers/middleware directly:
23  *
24  *   - [formidable](https://github.com/felixge/node-formidable)
25  *   - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) or [multiparty]
26  *   - [connect-busboy](https://github.com/mscdex/connect-busboy) or [busboy](https://github.com/mscdex/busboy)
27  *
28  * Parse multipart/form-data request bodies,
29  * providing the parsed object as `req.body`
30  * and `req.files`.
31  *
32  * Configuration:
33  *
34  *  The options passed are merged with [multiparty](https://github.com/superjoe30/node-multiparty)'s
35  *  `Form` object, allowing you to configure the upload directory,
36  *  size limits, etc. For example if you wish to change the upload dir do the following.
37  *
38  *     app.use(connect.multipart({ uploadDir: path }));
39  *
40  * Options:
41  *
42  *   - `limit`  byte limit defaulting to [100mb]
43  *   - `defer`  defers processing and exposes the multiparty form object as `req.form`.
44  *              `next()` is called without waiting for the form's "end" event.
45  *              This option is useful if you need to bind to the "progress" or "part" events, for example.
46  *
47  * Temporary Files:
48  *
49  *  By default temporary files are used, stored in `os.tmpDir()`. These
50  *  are not automatically garbage collected, you are in charge of moving them
51  *  or deleting them. When `defer` is not used and these files are created you
52  *  may refernce them via the `req.files` object.
53  *
54  *     req.files.images.forEach(function(file){
55  *       console.log('  uploaded : %s %skb : %s', file.originalFilename, file.size / 1024 | 0, file.path);
56  *     });
57  *
58  *  It is highly recommended to monitor and clean up tempfiles in any production
59  *  environment, you may use tools like [reap](https://github.com/visionmedia/reap)
60  *  to do so.
61  *
62  * Streaming:
63  *
64  *  When `defer` is used files are _not_ streamed to tmpfiles, you may
65  *  access them via the "part" events and stream them accordingly:
66  *
67  *     req.form.on('part', function(part){
68  *       // transfer to s3 etc
69  *       console.log('upload %s %s', part.name, part.filename);
70  *       var out = fs.createWriteStream('/tmp/' + part.filename);
71  *       part.pipe(out);
72  *     });
73  *
74  *     req.form.on('close', function(){
75  *       res.end('uploaded!');
76  *     });
77  *
78  * @param {Object} options
79  * @return {Function}
80  * @api public
81  */
82
83 exports = module.exports = function(options){
84   options = options || {};
85
86   var limit = _limit(options.limit || '100mb');
87
88   return function multipart(req, res, next) {
89     if (req._body) return next();
90     req.body = req.body || {};
91     req.files = req.files || {};
92
93     // ignore GET
94     if ('GET' == req.method || 'HEAD' == req.method) return next();
95
96     // check Content-Type
97     if (!typeis(req, 'multipart')) return next();
98
99     // flag as parsed
100     req._body = true;
101
102     // parse
103     limit(req, res, function(err){
104       if (err) return next(err);
105
106       var form = new multiparty.Form(options)
107         , data = {}
108         , files = {}
109         , done;
110
111       Object.keys(options).forEach(function(key){
112         form[key] = options[key];
113       });
114
115       function ondata(name, val, data){
116         if (Array.isArray(data[name])) {
117           data[name].push(val);
118         } else if (data[name]) {
119           data[name] = [data[name], val];
120         } else {
121           data[name] = val;
122         }
123       }
124
125       form.on('field', function(name, val){
126         ondata(name, val, data);
127       });
128
129       if (!options.defer) {
130         form.on('file', function(name, val){
131           val.name = val.originalFilename;
132           val.type = val.headers['content-type'] || null;
133           ondata(name, val, files);
134         });
135       }
136
137       form.on('error', function(err){
138         if (!options.defer) {
139           err.status = 400;
140           next(err);
141         }
142         done = true;
143       });
144
145       form.on('close', function(){
146         if (done) return;
147         try {
148           req.body = qs.parse(data, { allowDots: false, allowPrototypes: true });
149           req.files = qs.parse(files, { allowDots: false, allowPrototypes: true });
150         } catch (err) {
151           form.emit('error', err);
152           return;
153         }
154         if (!options.defer) next();
155       });
156
157       form.parse(req);
158
159       if (options.defer) {
160         req.form = form;
161         next();
162       }
163     });
164   }
165 };
166
167 module.exports = deprecate.function(module.exports,
168   'multipart: use parser (multiparty, busboy, formidable) npm module instead');