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.

utils.js 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /**
  2. * Module dependencies.
  3. */
  4. var mime = require('send').mime;
  5. var basename = require('path').basename;
  6. var etag = require('etag');
  7. var proxyaddr = require('proxy-addr');
  8. var qs = require('qs');
  9. var querystring = require('querystring');
  10. var typer = require('media-typer');
  11. /**
  12. * Return strong ETag for `body`.
  13. *
  14. * @param {String|Buffer} body
  15. * @param {String} [encoding]
  16. * @return {String}
  17. * @api private
  18. */
  19. exports.etag = function (body, encoding) {
  20. var buf = !Buffer.isBuffer(body)
  21. ? new Buffer(body, encoding)
  22. : body
  23. return etag(buf, {weak: false})
  24. };
  25. /**
  26. * Return weak ETag for `body`.
  27. *
  28. * @param {String|Buffer} body
  29. * @param {String} [encoding]
  30. * @return {String}
  31. * @api private
  32. */
  33. exports.wetag = function wetag(body, encoding){
  34. var buf = !Buffer.isBuffer(body)
  35. ? new Buffer(body, encoding)
  36. : body
  37. return etag(buf, {weak: true})
  38. };
  39. /**
  40. * Check if `path` looks absolute.
  41. *
  42. * @param {String} path
  43. * @return {Boolean}
  44. * @api private
  45. */
  46. exports.isAbsolute = function(path){
  47. if ('/' == path[0]) return true;
  48. if (':' == path[1] && '\\' == path[2]) return true;
  49. if ('\\\\' == path.substring(0, 2)) return true; // Microsoft Azure absolute path
  50. };
  51. /**
  52. * Flatten the given `arr`.
  53. *
  54. * @param {Array} arr
  55. * @return {Array}
  56. * @api private
  57. */
  58. exports.flatten = function(arr, ret){
  59. ret = ret || [];
  60. var len = arr.length;
  61. for (var i = 0; i < len; ++i) {
  62. if (Array.isArray(arr[i])) {
  63. exports.flatten(arr[i], ret);
  64. } else {
  65. ret.push(arr[i]);
  66. }
  67. }
  68. return ret;
  69. };
  70. /**
  71. * Normalize the given `type`, for example "html" becomes "text/html".
  72. *
  73. * @param {String} type
  74. * @return {Object}
  75. * @api private
  76. */
  77. exports.normalizeType = function(type){
  78. return ~type.indexOf('/')
  79. ? acceptParams(type)
  80. : { value: mime.lookup(type), params: {} };
  81. };
  82. /**
  83. * Normalize `types`, for example "html" becomes "text/html".
  84. *
  85. * @param {Array} types
  86. * @return {Array}
  87. * @api private
  88. */
  89. exports.normalizeTypes = function(types){
  90. var ret = [];
  91. for (var i = 0; i < types.length; ++i) {
  92. ret.push(exports.normalizeType(types[i]));
  93. }
  94. return ret;
  95. };
  96. /**
  97. * Generate Content-Disposition header appropriate for the filename.
  98. * non-ascii filenames are urlencoded and a filename* parameter is added
  99. *
  100. * @param {String} filename
  101. * @return {String}
  102. * @api private
  103. */
  104. exports.contentDisposition = function(filename){
  105. var ret = 'attachment';
  106. if (filename) {
  107. filename = basename(filename);
  108. // if filename contains non-ascii characters, add a utf-8 version ala RFC 5987
  109. ret = /[^\040-\176]/.test(filename)
  110. ? 'attachment; filename="' + encodeURI(filename) + '"; filename*=UTF-8\'\'' + encodeURI(filename)
  111. : 'attachment; filename="' + filename + '"';
  112. }
  113. return ret;
  114. };
  115. /**
  116. * Parse accept params `str` returning an
  117. * object with `.value`, `.quality` and `.params`.
  118. * also includes `.originalIndex` for stable sorting
  119. *
  120. * @param {String} str
  121. * @return {Object}
  122. * @api private
  123. */
  124. function acceptParams(str, index) {
  125. var parts = str.split(/ *; */);
  126. var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index };
  127. for (var i = 1; i < parts.length; ++i) {
  128. var pms = parts[i].split(/ *= */);
  129. if ('q' == pms[0]) {
  130. ret.quality = parseFloat(pms[1]);
  131. } else {
  132. ret.params[pms[0]] = pms[1];
  133. }
  134. }
  135. return ret;
  136. }
  137. /**
  138. * Compile "etag" value to function.
  139. *
  140. * @param {Boolean|String|Function} val
  141. * @return {Function}
  142. * @api private
  143. */
  144. exports.compileETag = function(val) {
  145. var fn;
  146. if (typeof val === 'function') {
  147. return val;
  148. }
  149. switch (val) {
  150. case true:
  151. fn = exports.wetag;
  152. break;
  153. case false:
  154. break;
  155. case 'strong':
  156. fn = exports.etag;
  157. break;
  158. case 'weak':
  159. fn = exports.wetag;
  160. break;
  161. default:
  162. throw new TypeError('unknown value for etag function: ' + val);
  163. }
  164. return fn;
  165. }
  166. /**
  167. * Compile "query parser" value to function.
  168. *
  169. * @param {String|Function} val
  170. * @return {Function}
  171. * @api private
  172. */
  173. exports.compileQueryParser = function compileQueryParser(val) {
  174. var fn;
  175. if (typeof val === 'function') {
  176. return val;
  177. }
  178. switch (val) {
  179. case true:
  180. fn = querystring.parse;
  181. break;
  182. case false:
  183. fn = newObject;
  184. break;
  185. case 'extended':
  186. fn = qs.parse;
  187. break;
  188. case 'simple':
  189. fn = querystring.parse;
  190. break;
  191. default:
  192. throw new TypeError('unknown value for query parser function: ' + val);
  193. }
  194. return fn;
  195. }
  196. /**
  197. * Compile "proxy trust" value to function.
  198. *
  199. * @param {Boolean|String|Number|Array|Function} val
  200. * @return {Function}
  201. * @api private
  202. */
  203. exports.compileTrust = function(val) {
  204. if (typeof val === 'function') return val;
  205. if (val === true) {
  206. // Support plain true/false
  207. return function(){ return true };
  208. }
  209. if (typeof val === 'number') {
  210. // Support trusting hop count
  211. return function(a, i){ return i < val };
  212. }
  213. if (typeof val === 'string') {
  214. // Support comma-separated values
  215. val = val.split(/ *, */);
  216. }
  217. return proxyaddr.compile(val || []);
  218. }
  219. /**
  220. * Set the charset in a given Content-Type string.
  221. *
  222. * @param {String} type
  223. * @param {String} charset
  224. * @return {String}
  225. * @api private
  226. */
  227. exports.setCharset = function(type, charset){
  228. if (!type || !charset) return type;
  229. // parse type
  230. var parsed = typer.parse(type);
  231. // set charset
  232. parsed.parameters.charset = charset;
  233. // format type
  234. return typer.format(parsed);
  235. };
  236. /**
  237. * Return new empty objet.
  238. *
  239. * @return {Object}
  240. * @api private
  241. */
  242. function newObject() {
  243. return {};
  244. }