UNPKG

whistle

Version:

HTTP, HTTP2, HTTPS, Websocket debugging proxy

114 lines (106 loc) 2.57 kB
var Transform = require('stream').Transform; var OPTIONS = { highWaterMark: 0, objectMode: true }; var LF = Buffer.from('\n'); function getBuffer(data) { return Buffer.isBuffer(data) ? data : Buffer.from(String(data)); } function pack(data) { if (!data) { return Buffer.from('\n0\n'); } data = getBuffer(data); return Buffer.concat([Buffer.from('\n' + data.length + '\n'), data]); } exports.pack = pack; exports.getEncodeTransform = function () { var trans = new Transform(OPTIONS); trans._transform = function (chunk, _, cb) { cb(null, pack(chunk)); }; trans.push_ = trans.push; trans.push = function (chunk, encoding) { if (chunk) { return trans.push_(chunk, encoding); } }; trans.end_ = trans.end; trans.end = function (chunk) { return trans.end_(function () { chunk && trans.push_(pack(chunk)); trans.push_(pack()); }); }; return trans; }; function Parser() { var buf; var len = 0; var parseChunk = function () { if (len <= 0) { var index = buf.indexOf(LF, 1); if (index === -1) { return; } len = parseInt(String(buf.slice(1, index)), 10); if (!len) { return false; } buf = buf.slice(index + 1); if (!buf.length) { return; } } var curLen = len; var chunk = buf.slice(0, curLen); len -= chunk.length; buf = buf.length > curLen ? buf.slice(curLen) : null; return chunk; }; var self = this; self.write = function (chunk) { if (chunk) { buf = buf ? Buffer.concat([buf, chunk]) : chunk; } else if (!buf) { return; } var data = parseChunk(); if (data === false) { return self.onEnd && self.onEnd(); } if (!data) { if (chunk === false) { return; } return self.onContinue && self.onContinue(); } self.onData && self.onData(data); self.write(false); }; } exports.getDecodeTransform = function () { var trans = new Transform(OPTIONS); var parser = new Parser(); var transCb, data; parser.onEnd = function () { data && trans.push(data); trans.push(null); }; parser.onContinue = function () { if (transCb) { transCb(); transCb = null; } }; parser.onData = function (chunk) { data = data ? Buffer.concat([data, chunk]) : chunk; if (transCb) { transCb(null, data); transCb = data = null; } }; trans._transform = function (chunk, _, cb) { transCb = cb; chunk && parser.write(getBuffer(chunk)); }; return trans; };