mirror of
https://github.com/socketio/socket.io.git
synced 2026-04-30 03:00:39 -04:00
155 lines
2.6 KiB
JavaScript
155 lines
2.6 KiB
JavaScript
|
|
/**
|
|
* Packet types.
|
|
*/
|
|
|
|
var packets = exports.packets = {
|
|
open: 0 // non-ws
|
|
, close: 1 // non-ws
|
|
, ping: 2
|
|
, pong: 3
|
|
, message: 4
|
|
, error: 5
|
|
, upgrade: 6
|
|
};
|
|
|
|
var packetslist = Object.keys(packets);
|
|
|
|
/**
|
|
* Premade error packet.
|
|
*/
|
|
|
|
var err = { type: 'error', data: 'parser error' }
|
|
|
|
/**
|
|
* Encodes a packet.
|
|
*
|
|
* <packet type id> [ `:` <data> ]
|
|
*
|
|
* Example:
|
|
*
|
|
* 5:hello world
|
|
* 3
|
|
* 4
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
exports.encodePacket = function (packet) {
|
|
var encoded = packets[packet.type]
|
|
|
|
// data fragment is optional
|
|
if (undefined !== packet.data) {
|
|
encoded += packet.data;
|
|
}
|
|
|
|
return '' + encoded;
|
|
};
|
|
|
|
/**
|
|
* Decodes a packet.
|
|
*
|
|
* @return {Object} with `type` and `data` (if any)
|
|
* @api private
|
|
*/
|
|
|
|
exports.decodePacket = function (data) {
|
|
var type = data.charAt(0)
|
|
if (Number(type) != type || !packetslist[type]) return err;
|
|
if (data.length > 1) {
|
|
return { type: packetslist[type], data: data.substring(1) };
|
|
} else {
|
|
return { type: packetslist[type] };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Encodes multiple messages (payload).
|
|
*
|
|
* <length>:data
|
|
*
|
|
* Example:
|
|
*
|
|
* 11:hello world2:hi
|
|
*
|
|
* @param {Array} packets
|
|
* @api private
|
|
*/
|
|
|
|
exports.encodePayload = function (packets) {
|
|
if (!packets.length) {
|
|
return '0:';
|
|
}
|
|
|
|
var encoded = ''
|
|
, message
|
|
|
|
for (var i = 0, l = packets.length; i < l; i++) {
|
|
message = exports.encodePacket(packets[i]);
|
|
encoded += message.length + ':' + message;
|
|
}
|
|
|
|
return encoded;
|
|
};
|
|
|
|
/*
|
|
* Decodes data when a payload is maybe expected.
|
|
*
|
|
* @param {String} data
|
|
* @return {Array} packets
|
|
* @api public
|
|
*/
|
|
|
|
exports.decodePayload = function (data) {
|
|
if (data == '') {
|
|
// parser error - ignoring payload
|
|
return [err];
|
|
}
|
|
|
|
var packets = []
|
|
, length = ''
|
|
, n, msg, packet
|
|
|
|
for (var i = 0, l = data.length; i < l; i++) {
|
|
var chr = data[i]
|
|
|
|
if (':' != chr) {
|
|
length += chr;
|
|
} else {
|
|
if ('' == length || (length != (n = Number(length)))) {
|
|
// parser error - ignoring payload
|
|
return [err];
|
|
}
|
|
|
|
msg = data.substr(i + 1, n);
|
|
|
|
if (length != msg.length) {
|
|
// parser error - ignoring payload
|
|
return [err];
|
|
}
|
|
|
|
if (msg.length) {
|
|
packet = exports.decodePacket(msg);
|
|
|
|
if (err.type == packet.type && err.data == packet.data) {
|
|
// parser error in individual packet - ignoring payload
|
|
return [err];
|
|
}
|
|
|
|
packets.push(packet);
|
|
}
|
|
|
|
// advance cursor
|
|
i += n;
|
|
length = ''
|
|
}
|
|
}
|
|
|
|
if (length != '') {
|
|
// parser error - ignoring payload
|
|
return [err];
|
|
}
|
|
|
|
return packets;
|
|
};
|