Ein Projekt das es ermöglicht Beerpong über das Internet von zwei unabhängigen positionen aus zu spielen. Entstehung im Rahmen einer Praktikumsaufgabe im Fach Interaktion.
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.

index.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. var bytes = require('bytes')
  2. var iconv = require('iconv-lite')
  3. module.exports = function (stream, options, done) {
  4. if (options === true || typeof options === 'string') {
  5. // short cut for encoding
  6. options = {
  7. encoding: options
  8. }
  9. }
  10. options = options || {}
  11. if (typeof options === 'function') {
  12. done = options
  13. options = {}
  14. }
  15. // get encoding
  16. var encoding = options.encoding !== true
  17. ? options.encoding
  18. : 'utf-8'
  19. // convert the limit to an integer
  20. var limit = null
  21. if (typeof options.limit === 'number')
  22. limit = options.limit
  23. if (typeof options.limit === 'string')
  24. limit = bytes(options.limit)
  25. // convert the expected length to an integer
  26. var length = null
  27. if (options.length != null && !isNaN(options.length))
  28. length = parseInt(options.length, 10)
  29. // check the length and limit options.
  30. // note: we intentionally leave the stream paused,
  31. // so users should handle the stream themselves.
  32. if (limit !== null && length !== null && length > limit) {
  33. var err = makeError('request entity too large', 'entity.too.large')
  34. err.status = err.statusCode = 413
  35. err.length = err.expected = length
  36. err.limit = limit
  37. cleanup()
  38. halt(stream)
  39. process.nextTick(function () {
  40. done(err)
  41. })
  42. return defer
  43. }
  44. // streams1: assert request encoding is buffer.
  45. // streams2+: assert the stream encoding is buffer.
  46. // stream._decoder: streams1
  47. // state.encoding: streams2
  48. // state.decoder: streams2, specifically < 0.10.6
  49. var state = stream._readableState
  50. if (stream._decoder || (state && (state.encoding || state.decoder))) {
  51. // developer error
  52. var err = makeError('stream encoding should not be set',
  53. 'stream.encoding.set')
  54. err.status = err.statusCode = 500
  55. cleanup()
  56. halt(stream)
  57. process.nextTick(function () {
  58. done(err)
  59. })
  60. return defer
  61. }
  62. var received = 0
  63. var decoder
  64. try {
  65. decoder = getDecoder(encoding)
  66. } catch (err) {
  67. cleanup()
  68. halt(stream)
  69. process.nextTick(function () {
  70. done(err)
  71. })
  72. return defer
  73. }
  74. var buffer = decoder
  75. ? ''
  76. : []
  77. stream.on('data', onData)
  78. stream.once('end', onEnd)
  79. stream.once('error', onEnd)
  80. stream.once('close', cleanup)
  81. return defer
  82. // yieldable support
  83. function defer(fn) {
  84. done = fn
  85. }
  86. function onData(chunk) {
  87. received += chunk.length
  88. decoder
  89. ? buffer += decoder.write(chunk)
  90. : buffer.push(chunk)
  91. if (limit !== null && received > limit) {
  92. var err = makeError('request entity too large', 'entity.too.large')
  93. err.status = err.statusCode = 413
  94. err.received = received
  95. err.limit = limit
  96. cleanup()
  97. halt(stream)
  98. done(err)
  99. }
  100. }
  101. function onEnd(err) {
  102. if (err) {
  103. cleanup()
  104. halt(stream)
  105. done(err)
  106. } else if (length !== null && received !== length) {
  107. err = makeError('request size did not match content length',
  108. 'request.size.invalid')
  109. err.status = err.statusCode = 400
  110. err.received = received
  111. err.length = err.expected = length
  112. cleanup()
  113. done(err)
  114. } else {
  115. var string = decoder
  116. ? buffer + (decoder.end() || '')
  117. : Buffer.concat(buffer)
  118. cleanup()
  119. done(null, string)
  120. }
  121. }
  122. function cleanup() {
  123. received = buffer = null
  124. stream.removeListener('data', onData)
  125. stream.removeListener('end', onEnd)
  126. stream.removeListener('error', onEnd)
  127. stream.removeListener('close', cleanup)
  128. }
  129. }
  130. function getDecoder(encoding) {
  131. if (!encoding) return null
  132. try {
  133. return iconv.getCodec(encoding).decoder()
  134. } catch (e) {
  135. var err = makeError('specified encoding unsupported', 'encoding.unsupported')
  136. err.status = err.statusCode = 415
  137. err.encoding = encoding
  138. throw err
  139. }
  140. }
  141. /**
  142. * Halt a stream.
  143. *
  144. * @param {Object} stream
  145. * @api private
  146. */
  147. function halt(stream) {
  148. // unpipe everything from the stream
  149. unpipe(stream)
  150. // pause stream
  151. if (typeof stream.pause === 'function') {
  152. stream.pause()
  153. }
  154. }
  155. // to create serializable errors you must re-set message so
  156. // that it is enumerable and you must re configure the type
  157. // property so that is writable and enumerable
  158. function makeError(message, type) {
  159. var error = new Error()
  160. error.message = message
  161. Object.defineProperty(error, 'type', {
  162. value: type,
  163. enumerable: true,
  164. writable: true,
  165. configurable: true
  166. })
  167. return error
  168. }
  169. /**
  170. * Unpipe everything from a stream.
  171. *
  172. * @param {Object} stream
  173. * @api private
  174. */
  175. /* istanbul ignore next: implementation differs between versions */
  176. function unpipe(stream) {
  177. if (typeof stream.unpipe === 'function') {
  178. // new-style
  179. stream.unpipe()
  180. return
  181. }
  182. // Node.js 0.8 hack
  183. var listener
  184. var listeners = stream.listeners('close')
  185. for (var i = 0; i < listeners.length; i++) {
  186. listener = listeners[i]
  187. if (listener.name !== 'cleanup' && listener.name !== 'onclose') {
  188. continue
  189. }
  190. // invoke the listener
  191. listener.call(stream)
  192. }
  193. }