Initial commit for OpenECOMP SDN-C OA&M
[sdnc/oam.git] / dgbuilder / dgeflows / node_modules / body-parser / lib / read.js
1 /*!
2  * body-parser
3  * Copyright(c) 2014 Douglas Christopher Wilson
4  * MIT Licensed
5  */
6
7 /**
8  * Module dependencies.
9  */
10
11 var getBody = require('raw-body')
12 var iconv = require('iconv-lite')
13 var onFinished = require('on-finished')
14 var typer = require('media-typer')
15 var zlib = require('zlib')
16
17 /**
18  * Module exports.
19  */
20
21 module.exports = read
22
23 /**
24  * Read a request into a buffer and parse.
25  *
26  * @param {object} req
27  * @param {object} res
28  * @param {function} next
29  * @param {function} parse
30  * @param {object} options
31  * @api private
32  */
33
34 function read(req, res, next, parse, options) {
35   var length
36   var stream
37
38   // flag as parsed
39   req._body = true
40
41   try {
42     stream = contentstream(req, options.inflate)
43     length = stream.length
44     delete stream.length
45   } catch (err) {
46     return next(err)
47   }
48
49   options = options || {}
50   options.length = length
51
52   var encoding = options.encoding !== null
53     ? options.encoding || 'utf-8'
54     : null
55   var verify = options.verify
56
57   options.encoding = verify
58     ? null
59     : encoding
60
61   // read body
62   getBody(stream, options, function (err, body) {
63     if (err) {
64       if (!err.status) {
65         err.status = 400
66       }
67
68       // echo back charset
69       if (err.type === 'encoding.unsupported') {
70         err = new Error('unsupported charset "' + encoding.toUpperCase() + '"')
71         err.charset = encoding.toLowerCase()
72         err.status = 415
73       }
74
75       // read off entire request
76       stream.resume()
77       onFinished(req, function onfinished() {
78         next(err)
79       })
80       return
81     }
82
83     // verify
84     if (verify) {
85       try {
86         verify(req, res, body, encoding)
87       } catch (err) {
88         if (!err.status) err.status = 403
89         return next(err)
90       }
91     }
92
93     // parse
94     try {
95       body = typeof body !== 'string' && encoding !== null
96         ? iconv.decode(body, encoding)
97         : body
98       req.body = parse(body)
99     } catch (err) {
100       if (!err.status) {
101         err.body = body
102         err.status = 400
103       }
104       return next(err)
105     }
106
107     next()
108   })
109 }
110
111 /**
112  * Get the content stream of the request.
113  *
114  * @param {object} req
115  * @param {boolean} [inflate=true]
116  * @return {object}
117  * @api private
118  */
119
120 function contentstream(req, inflate) {
121   var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
122   var err
123   var length = req.headers['content-length']
124   var stream
125
126   if (inflate === false && encoding !== 'identity') {
127     err = new Error('content encoding unsupported')
128     err.status = 415
129     throw err
130   }
131
132   switch (encoding) {
133     case 'deflate':
134       stream = zlib.createInflate()
135       req.pipe(stream)
136       break
137     case 'gzip':
138       stream = zlib.createGunzip()
139       req.pipe(stream)
140       break
141     case 'identity':
142       stream = req
143       stream.length = length
144       break
145     default:
146       err = new Error('unsupported content encoding "' + encoding + '"')
147       err.encoding = encoding
148       err.status = 415
149       throw err
150   }
151
152   return stream
153 }