Name: js-handler/node_modules/restify/lib/plugins/body_reader.js 
1:
// Copyright 2012 Mark Cavage, Inc.  All rights reserved.
2:
 
3:
var crypto = require('crypto');
4:
var zlib = require('zlib');
5:
 
6:
var assert = require('assert-plus');
7:
 
8:
var errors = require('../errors');
9:
 
10:
 
11:
 
12:
///--- Globals
13:
 
14:
var BadDigestError = errors.BadDigestError;
15:
var InvalidContentError = errors.InvalidContentError;
16:
var RequestEntityTooLargeError = errors.RequestEntityTooLargeError;
17:
 
18:
var MD5_MSG = 'Content-MD5 \'%s\' didn\'t match \'%s\'';
19:
 
20:
 
21:
 
22:
///--- Helpers
23:
 
24:
function createBodyWriter(req) {
25:
        var contentType = req.contentType();
26:
        if (!contentType ||
27:
            contentType === 'application/json' ||
28:
            contentType === 'application/x-www-form-urlencoded' ||
29:
            contentType === 'multipart/form-data' ||
30:
            contentType.substr(0, 5) === 'text/') {
31:
 
32:
                req.body = '';
33:
                return (function (chunk) {
34:
                        req.body += chunk.toString('utf8');
35:
                });
36:
        }
37:
 
38:
        req.body = new Buffer(0);
39:
        return (function (chunk) {
40:
                req.body = Buffer.concat([req.body, chunk]);
41:
        });
42:
}
43:
 
44:
 
45:
 
46:
///--- API
47:
 
48:
function bodyReader(options) {
49:
        options = options || {};
50:
        assert.object(options, 'options');
51:
 
52:
        var maxBodySize = options.maxBodySize || 0;
53:
 
54:
        function readBody(req, res, next) {
55:
                if ((req.getContentLength() === 0 && !req.isChunked()) ||
56:
                    req.contentType() === 'multipart/form-data') {
57:
                        next();
58:
                        return;
59:
                }
60:
                var bodyWriter = createBodyWriter(req);
61:
 
62:
                function done() {
63:
                        if (maxBodySize && bytesReceived > maxBodySize) {
64:
                                var msg = 'Request body size exceeds ' +
65:
                                        maxBodySize;
66:
                                next(new RequestEntityTooLargeError(msg));
67:
                                return;
68:
                        }
69:
 
70:
                        if (!req.body.length) {
71:
                                next();
72:
                                return;
73:
                        }
74:
 
75:
                        if (hash && md5 !== (digest = hash.digest('base64'))) {
76:
                                next(new BadDigestError(MD5_MSG, md5, digest));
77:
                                return;
78:
                        }
79:
 
80:
                        next();
81:
                }
82:
 
83:
                var bytesReceived = 0;
84:
                var digest;
85:
                var gz;
86:
                var hash;
87:
                var md5;
88:
                if ((md5 = req.headers['content-md5']))
89:
                        hash = crypto.createHash('md5');
90:
 
91:
                if (req.headers['content-encoding'] === 'gzip') {
92:
                        gz = zlib.createGunzip();
93:
                        gz.on('data', function onData(chunk) {
94:
                                bodyWriter(chunk);
95:
                        });
96:
                        gz.once('end', done);
97:
                        req.once('end', gz.end.bind(gz));
98:
                } else {
99:
                        req.once('end', done);
100:
                }
101:
 
102:
                req.on('data', function onRequestData(chunk) {
103:
                        if (maxBodySize) {
104:
                                bytesReceived += chunk.length;
105:
                                if (bytesReceived > maxBodySize)
106:
                                        return;
107:
                        }
108:
 
109:
                        if (hash)
110:
                                hash.update(chunk, 'binary');
111:
 
112:
                        if (gz) {
113:
                                gz.write(chunk);
114:
                        } else {
115:
                                bodyWriter(chunk);
116:
                        }
117:
                });
118:
 
119:
                req.once('error', next);
120:
                req.resume();
121:
        }
122:
 
123:
        return (readBody);
124:
}
125:
 
126:
module.exports = bodyReader;