| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | 'use strict';var TOKEN    = /([!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+)/,    NOTOKEN  = /([^!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z])/g,    QUOTED   = /"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"\\])*)"/,    PARAM    = new RegExp(TOKEN.source + '(?:=(?:' + TOKEN.source + '|' + QUOTED.source + '))?'),    EXT      = new RegExp(TOKEN.source + '(?: *; *' + PARAM.source + ')*', 'g'),    EXT_LIST = new RegExp('^' + EXT.source + '(?: *, *' + EXT.source + ')*$'),    NUMBER   = /^-?(0|[1-9][0-9]*)(\.[0-9]+)?$/;var hasOwnProperty = Object.prototype.hasOwnProperty;var Parser = {  parseHeader: function(header) {    var offers = new Offers();    if (header === '' || header === undefined) return offers;    if (!EXT_LIST.test(header))      throw new SyntaxError('Invalid Sec-WebSocket-Extensions header: ' + header);    var values = header.match(EXT);    values.forEach(function(value) {      var params = value.match(new RegExp(PARAM.source, 'g')),          name   = params.shift(),          offer  = {};      params.forEach(function(param) {        var args = param.match(PARAM), key = args[1], data;        if (args[2] !== undefined) {          data = args[2];        } else if (args[3] !== undefined) {          data = args[3].replace(/\\/g, '');        } else {          data = true;        }        if (NUMBER.test(data)) data = parseFloat(data);        if (hasOwnProperty.call(offer, key)) {          offer[key] = [].concat(offer[key]);          offer[key].push(data);        } else {          offer[key] = data;        }      }, this);      offers.push(name, offer);    }, this);    return offers;  },  serializeParams: function(name, params) {    var values = [];    var print = function(key, value) {      if (value instanceof Array) {        value.forEach(function(v) { print(key, v) });      } else if (value === true) {        values.push(key);      } else if (typeof value === 'number') {        values.push(key + '=' + value);      } else if (NOTOKEN.test(value)) {        values.push(key + '="' + value.replace(/"/g, '\\"') + '"');      } else {        values.push(key + '=' + value);      }    };    for (var key in params) print(key, params[key]);    return [name].concat(values).join('; ');  }};var Offers = function() {  this._byName  = {};  this._inOrder = [];};Offers.prototype.push = function(name, params) {  if (!hasOwnProperty.call(this._byName, name))    this._byName[name] = [];  this._byName[name].push(params);  this._inOrder.push({ name: name, params: params });};Offers.prototype.eachOffer = function(callback, context) {  var list = this._inOrder;  for (var i = 0, n = list.length; i < n; i++)    callback.call(context, list[i].name, list[i].params);};Offers.prototype.byName = function(name) {  return this._byName[name] || [];};Offers.prototype.toArray = function() {  return this._inOrder.slice();};module.exports = Parser;
 |