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.

77 lines
1.9 KiB

  1. /*!
  2. * Connect - limit
  3. * Copyright(c) 2011 TJ Holowaychuk
  4. * MIT Licensed
  5. */
  6. /**
  7. * Module dependencies.
  8. */
  9. var utils = require('../utils'),
  10. brokenPause = utils.brokenPause;
  11. /**
  12. * Limit:
  13. *
  14. * Limit request bodies to the given size in `bytes`.
  15. *
  16. * A string representation of the bytesize may also be passed,
  17. * for example "5mb", "200kb", "1gb", etc.
  18. *
  19. * connect()
  20. * .use(connect.limit('5.5mb'))
  21. * .use(handleImageUpload)
  22. *
  23. * @param {Number|String} bytes
  24. * @return {Function}
  25. * @api public
  26. */
  27. module.exports = function limit(bytes){
  28. if ('string' == typeof bytes) bytes = utils.parseBytes(bytes);
  29. if ('number' != typeof bytes) throw new Error('limit() bytes required');
  30. return function limit(req, res, next){
  31. var received = 0
  32. , len = req.headers['content-length']
  33. ? parseInt(req.headers['content-length'], 10)
  34. : null;
  35. // self-awareness
  36. if (req._limit) return next();
  37. req._limit = true;
  38. // limit by content-length
  39. if (len && len > bytes) return next(utils.error(413));
  40. // limit
  41. if (brokenPause) {
  42. listen();
  43. } else {
  44. req.on('newListener', function handler(event) {
  45. if (event !== 'data') return;
  46. req.removeListener('newListener', handler);
  47. // Start listening at the end of the current loop
  48. // otherwise the request will be consumed too early.
  49. // Sideaffect is `limit` will miss the first chunk,
  50. // but that's not a big deal.
  51. // Unfortunately, the tests don't have large enough
  52. // request bodies to test this.
  53. process.nextTick(listen);
  54. });
  55. };
  56. next();
  57. function listen() {
  58. req.on('data', function(chunk) {
  59. received += Buffer.isBuffer(chunk)
  60. ? chunk.length :
  61. Buffer.byteLength(chunk);
  62. if (received > bytes) req.destroy();
  63. });
  64. };
  65. };
  66. };