You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.6 KiB
82 lines
1.6 KiB
|
|
/*! |
|
* Connect - limit |
|
* Copyright(c) 2011 TJ Holowaychuk |
|
* MIT Licensed |
|
*/ |
|
|
|
/** |
|
* Limit request bodies to the given size in `bytes`. |
|
* |
|
* A string representation of the bytesize may also be passed, |
|
* for example "5mb", "200kb", "1gb", etc. |
|
* |
|
* Examples: |
|
* |
|
* var server = connect( |
|
* connect.limit('5.5mb') |
|
* ).listen(3000); |
|
* |
|
* TODO: pause EV_READ |
|
* |
|
* @param {Number|String} bytes |
|
* @return {Function} |
|
* @api public |
|
*/ |
|
|
|
module.exports = function limit(bytes){ |
|
if ('string' == typeof bytes) bytes = parse(bytes); |
|
if ('number' != typeof bytes) throw new Error('limit() bytes required'); |
|
return function limit(req, res, next){ |
|
var received = 0 |
|
, len = req.headers['content-length'] |
|
? parseInt(req.headers['content-length'], 10) |
|
: null; |
|
|
|
// deny the request |
|
function deny() { |
|
req.destroy(); |
|
} |
|
|
|
// self-awareness |
|
if (req._limit) return next(); |
|
req._limit = true; |
|
|
|
// limit by content-length |
|
if (len && len > bytes) { |
|
res.statusCode = 413; |
|
res.end('Request Entity Too Large'); |
|
return; |
|
} |
|
|
|
// limit |
|
req.on('data', function(chunk){ |
|
received += chunk.length; |
|
if (received > bytes) deny(); |
|
}); |
|
|
|
next(); |
|
}; |
|
}; |
|
|
|
/** |
|
* Parse byte `size` string. |
|
* |
|
* @param {String} size |
|
* @return {Number} |
|
* @api private |
|
*/ |
|
|
|
function parse(size) { |
|
var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/) |
|
, n = parseFloat(parts[1]) |
|
, type = parts[2]; |
|
|
|
var map = { |
|
kb: 1024 |
|
, mb: 1024 * 1024 |
|
, gb: 1024 * 1024 * 1024 |
|
}; |
|
|
|
return map[type] * n; |
|
} |