function Protocol(options) { Stream.call(this); options = options || {}; this.readable = true; this.writable = true; this._config = options.config || {}; this._connection = options.connection; this._callback = null; this._fatalError = null; this._quitSequence = null; this._handshakeSequence = null; this._handshaked = false; this._destroyed = false; this._queue = []; this._handshakeInitializationPacket = null; this._parser = new Parser({ onPacket : this._parsePacket.bind(this), config : this._config }); }
// Deprecated API: Socket(fd, type) // New API: Socket({ fd: 10, type: 'unix', allowHalfOpen: true }) function Socket(options) { if (!(this instanceof Socket)) return new Socket(arguments[0], arguments[1]); stream.Stream.call(this); this.bufferSize = 0; this.fd = null; this.type = null; this.allowHalfOpen = false; if (typeof options == 'object') { this.fd = options.fd !== undefined ? parseInt(options.fd, 10) : null; this.type = options.type || null; this.allowHalfOpen = options.allowHalfOpen || false; } else if (typeof options == 'number') { this.fd = arguments[0]; this.type = arguments[1]; } if (parseInt(this.fd, 10) >= 0) { this.open(this.fd, this.type); } else { setImplmentationMethods(this); } }
function Request (options) { // if given the method property in options, set property explicitMethod to true // extend the Request instance with any non-reserved properties // remove any reserved functions from the options object // set Request instance to be readable and writable // call init var self = this; // start with HAR, then override with additional options if (options.har) { self._har = new Har(self); options = self._har.options(options) } stream.Stream.call(self); var reserved = Object.keys(Request.prototype); var nonReserved = filterForNonReserved(reserved, options); extend(self, nonReserved); options = filterOutReservedFunctions(reserved, options); self.readable = true; self.writable = true; if (options.method) { self.explicitMethod = true } self._qs = new Querystring(self); self._auth = new Auth(self); self._oauth = new OAuth(self); self._multipart = new Multipart(self); self._redirect = new Redirect(self); self._tunnel = new Tunnel(self); self.init(options) }
function WebsocketStream(server, options) { if (!(this instanceof WebsocketStream)) return new WebsocketStream(server, options) stream.Stream.call(this) this.options = options || {} this.readable = true this.writable = true this._buffer = [] if (typeof server === "object") { this.ws = server this.ws.on('message', this.onMessage.bind(this)) this.ws.on('error', this.onError.bind(this)) this.ws.on('close', this.onClose.bind(this)) this.ws.on('open', this.onOpen.bind(this)) if (this.ws.readyState === 1) this._open = true } else { this.ws = new WebSocketPoly(server, this.options.protocol) this.ws.binaryType = this.options.binaryType || 'arraybuffer' this.ws.onmessage = this.onMessage.bind(this) this.ws.onerror = this.onError.bind(this) this.ws.onclose = this.onClose.bind(this) this.ws.onopen = this.onOpen.bind(this) } }
function FetchStream(url, options){ Stream.call(this); options = options || {}; this.url = url; if(!this.url){ return this.emit("error", new Error("url not defined")); } this.userAgent = options.userAgent || "FetchStream"; this._redirect_count = 0; this.options = options || {}; this.normalizeOptions(); // prevent errors before "error" handler is set by defferring actions if(typeof setImmediate != "undefined"){ setImmediate(this.runStream.bind(this, url)); }else{ process.nextTick(this.runStream.bind(this, url)); } }
function ReadStream(parentStream, opts) { var self = this; if (!(self instanceof ReadStream)) return new ReadStream(parentStream); Stream.call(self); self.parentStream = parentStream; self.readable = true; self.number = self.parentStream.readerNum += 1; self.paused = false; if (!opts.start) opts.start = 0; self.filepos = opts.start; if (!opts.end && opts.end !== 0) opts.end = -1; self.end = opts.end; // Check whether old data available process.nextTick(function () { self.checkOldData(); }); self.on('data', function (data) { self.filepos += data.length; }); self.on('end', function () { self.readable = false; }); self.on('error', function (e) { self.readable = false; }); }
function WriteStream (options, db) { this.__proto__.__proto__ = Stream.prototype Stream.call(this) this._options = extend(extend({}, defaultOptions), options) this._db = db this._buffer = [] this._status = 'init' this._end = false this.writable = true this.readable = false var ready = function () { if (!this.writable) return this._status = 'ready' this.emit('ready') this._process() }.bind(this) if (db.isOpen()) process.nextTick(ready) else db.once('ready', ready) }
function CountStream (max) { stream.Stream.call(this); if (typeof max !== 'number' || parseInt(max, 10) !== max || max <= 0 ) { throw new TypeError('"max" must be "Integer Number" and over "0"'); } this.max = max; this.count = 0; this.readable = true; this.once('close', function () { this.readable = false; this.emit('end'); }.bind(this)); this.on('error', function () { this.readable = false; }.bind(this)); }
function StreamTransformer(transformers) { Stream.call(this); this.writable = true; this._done = false; this.transformers = transformers || []; }
function RenovateStream() { this.readable = true; this.writable = true; Stream.call(this); }
var ReadStream = fs.ReadStream = function(path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); Stream.call(this); var self = this; this.path = path; this.fd = null; this.readable = true; this.paused = false; this.flags = 'r'; this.mode = 438; /*=0666*/ this.bufferSize = 64 * 1024; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.encoding) this.setEncoding(this.encoding); if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.end === undefined) { this.end = Infinity; } else if ('number' !== typeof this.end) { throw TypeError('end must be a Number'); } if (this.start > this.end) { throw new Error('start must be <= end'); } this.pos = this.start; } if (this.fd !== null) { this._read(); return; } fs.open(this.path, this.flags, this.mode, function(err, fd) { if (err) { self.emit('error', err); self.readable = false; return; } self.fd = fd; self.emit('open', fd); self._read(); }); };
function Publisher () { stream.Stream.call(this); this.readable = true; }
var Stream=require("stream").Stream;var utils=require("./utils");function QueryStream(a){Stream.call(this);this.query=a;this.readable=true;this.paused=false;this._cursor=null;this._destroyed=null;this._fields=null;this._ticks=0;this._inline=T_INIT;var b=this;process.nextTick(function(){b._init()})}
function Writable () { this.writable = true; stream.Stream.call(this); }
function Request (options) { var self = this stream.Stream.call(self) self.readable = true self.writable = true if (typeof options === 'string') { options = {uri:options} } var reserved = Object.keys(Request.prototype) for (var i in options) { if (reserved.indexOf(i) === -1) { self[i] = options[i] } else { if (typeof options[i] === 'function') { delete options[i] } } } options = copy(options) if (!self.pool) self.pool = globalPool self.dests = [] self.__isRequestRequest = true // Protect against double callback if (!self._callback && self.callback) { self._callback = self.callback self.callback = function () { if (self._callbackCalled) return // Print a warning maybe? self._callback.apply(self, arguments) self._callbackCalled = true } } if (self.url) { // People use this property instead all the time so why not just support it. self.uri = self.url delete self.url } if (!self.uri) { throw new Error("options.uri is a required argument") } else { if (typeof self.uri == "string") self.uri = url.parse(self.uri) } if (self.proxy) { if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) } self._redirectsFollowed = self._redirectsFollowed || 0 self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false; if (self.followRedirect || self.followAllRedirects) self.redirects = self.redirects || [] self.headers = self.headers ? copy(self.headers) : {} self.setHost = false if (!self.headers.host) { self.headers.host = self.uri.hostname if (self.uri.port) { if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && !(self.uri.port === 443 && self.uri.protocol === 'https:') ) self.headers.host += (':'+self.uri.port) } self.setHost = true } self.jar(options.jar) if (!self.uri.pathname) {self.uri.pathname = '/'} if (!self.uri.port) { if (self.uri.protocol == 'http:') {self.uri.port = 80} else if (self.uri.protocol == 'https:') {self.uri.port = 443} } if (self.proxy) { self.port = self.proxy.port self.host = self.proxy.hostname } else { self.port = self.uri.port self.host = self.uri.hostname } if (self.onResponse === true) { self.onResponse = self.callback delete self.callback } self.clientErrorHandler = function (error) { if (self.setHost) delete self.headers.host if (self.req._reusedSocket && error.code === 'ECONNRESET') { self.agent = {addRequest: ForeverAgent.prototype.addRequestNoreuse.bind(self.agent)} self.start() self.req.end() return } if (self.timeout && self.timeoutTimer) { clearTimeout(self.timeoutTimer); self.timeoutTimer = null; } self.emit('error', error) } if (self.onResponse) self.on('error', function (e) {self.onResponse(e)}) if (self.callback) self.on('error', function (e) {self.callback(e)}) if (options.form) { self.form(options.form) } if (options.oauth) { self.oauth(options.oauth) } if (self.uri.auth && !self.headers.authorization) { self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) } if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization']) { self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) } if (self.uri.path) { self.path = self.uri.path } else { self.path = self.uri.pathname + (self.uri.search || "") } if (self.path.length === 0) self.path = '/' if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) if (options.json) { self.json(options.json) } else if (options.multipart) { self.multipart(options.multipart) } if (self.body) { var length = 0 if (!Buffer.isBuffer(self.body)) { if (Array.isArray(self.body)) { for (var i = 0; i < self.body.length; i++) { length += self.body[i].length } } else { self.body = new Buffer(self.body) length = self.body.length } } else { length = self.body.length } if (length) { self.headers['content-length'] = length } else { throw new Error('Argument error, options.body.') } } var protocol = self.proxy ? self.proxy.protocol : self.uri.protocol , defaultModules = {'http:':http, 'https:':https} , httpModules = self.httpModules || {} ; self.httpModule = httpModules[protocol] || defaultModules[protocol] if (!self.httpModule) throw new Error("Invalid protocol") if (self.pool === false) { self.agent = false } else { if (self.maxSockets) { // Don't use our pooling if node has the refactored client self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port) self.agent.maxSockets = self.maxSockets } if (self.pool.maxSockets) { // Don't use our pooling if node has the refactored client self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port) self.agent.maxSockets = self.pool.maxSockets } } self.once('pipe', function (src) { if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") self.src = src if (isReadStream(src)) { if (!self.headers['content-type'] && !self.headers['Content-Type']) self.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1)) } else { if (src.headers) { for (var i in src.headers) { if (!self.headers[i]) { self.headers[i] = src.headers[i] } } } if (src.method && !self.method) { self.method = src.method } } self.on('pipe', function () { console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") }) }) process.nextTick(function () { if (self.body) { if (Array.isArray(self.body)) { self.body.forEach(function(part) { self.write(part) }) } else { self.write(self.body) } self.end() } else if (self.requestBodyStream) { console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") self.requestBodyStream.pipe(self) } else if (!self.src) { self.headers['content-length'] = 0 self.end() } self.ntick = true }) }
var MessageStream = function(message) { var self = this; stream.Stream.call(self); self.message = message; self.readable = true; self.paused = false; self.buffer = new Buffer(MIMECHUNK*24*7); self.bufferIndex = 0; var output_process = function(next, args) { if(self.paused) { self.resumed = function() { next.apply(null, args); }; } else { next.apply(null, args); } next.apply(null, args); }; var output_mixed = function() { var boundary = generate_boundary(); var data = ["Content-Type: multipart/mixed; boundary=\"", boundary, "\"", CRLF, CRLF, "--", boundary, CRLF]; output(data.join('')); if(!self.message.alternative) { output_text(self.message); output_message(boundary, self.message.attachments, 0, close); } else { output_alternative(self.message, function() { output_message(boundary, self.message.attachments, 0, close); }); } }; var output_message = function(boundary, list, index, callback) { if(index < list.length) { output(["--", boundary, CRLF].join('')); if(list[index].related) { output_related(list[index], function() { output_message(boundary, list, index + 1, callback); }); } else { output_attachment(list[index], function() { output_message(boundary, list, index + 1, callback); }); } } else { output([CRLF, "--", boundary, "--", CRLF, CRLF].join('')); callback(); } }; var output_attachment_headers = function(attachment) { var data = [], header, headers = { 'content-type': attachment.type + (attachment.charset ? "; charset=" + attachment.charset : "") + (attachment.method ? "; method=" + attachment.method : ""), 'content-transfer-encoding': 'base64', 'content-disposition': attachment.inline ? 'inline' : 'attachment; filename="' + mimelib.encodeMimeWord(attachment.name, 'Q', 'utf-8') + '"' }; for(header in (attachment.headers || {})) { // allow sender to override default headers headers[header.toLowerCase()] = attachment.headers[header]; } for(header in headers) { data = data.concat([fix_header_name_case(header), ': ', headers[header], CRLF]); } output(data.concat([CRLF]).join('')); }; var output_attachment = function(attachment, callback) { var build = attachment.path ? output_file : attachment.stream ? output_stream : output_data; output_attachment_headers(attachment); build(attachment, callback); }; var output_data = function(attachment, callback) { output_base64(attachment.encoded ? attachment.data : new Buffer(attachment.data).toString("base64"), callback); }; var output_file = function(attachment, next) { var chunk = MIME64CHUNK*16; var buffer = new Buffer(chunk); var closed = function(fd) { if(fs.close) { fs.close(fd); } }; var opened = function(err, fd) { if(!err) { var read = function(err, bytes) { if(!err && self.readable) { var encoding = attachment && attachment.headers ? attachment.headers['content-transfer-encoding'] || 'base64' : 'base64'; if (encoding === 'ascii' || encoding === '7bit') { encoding = 'ascii'; } else if(encoding === 'binary' || encoding === '8bit') { encoding = 'binary'; } else { encoding = 'base64'; } // guaranteed to be encoded without padding unless it is our last read output_base64(buffer.toString(encoding, 0, bytes), function() { if(bytes == chunk) // we read a full chunk, there might be more { fs.read(fd, buffer, 0, chunk, null, read); } else // that was the last chunk, we are done reading the file { self.removeListener("error", closed); fs.close(fd, next); } }); } else { self.emit('error', err || {message:"message stream was interrupted somehow!"}); } }; fs.read(fd, buffer, 0, chunk, null, read); self.once("error", closed); } else self.emit('error', err); }; fs.open(attachment.path, 'r', opened); }; var output_stream = function(attachment, callback) { if(attachment.stream.readable) { var previous = null; attachment.stream.resume(); attachment.stream.on('end', function() { output_base64((previous || new Buffer(0)).toString("base64"), callback); self.removeListener('pause', attachment.stream.pause); self.removeListener('resume', attachment.stream.resume); self.removeListener('error', attachment.stream.resume); }); attachment.stream.on('data', function(buffer) { // do we have bytes from a previous stream data event? if(previous) { var buffer2 = Buffer.concat([previous, buffer]); previous = null; // free up the buffer buffer = null; // free up the buffer buffer = buffer2; } var padded = buffer.length % (MIME64CHUNK); // encode as much of the buffer to base64 without empty bytes if(padded) { previous = new Buffer(padded); // copy dangling bytes into previous buffer buffer.copy(previous, 0, buffer.length - padded); } output_base64(buffer.toString("base64", 0, buffer.length - padded)); }); self.on('pause', attachment.stream.pause); self.on('resume', attachment.stream.resume); self.on('error', attachment.stream.resume); } else self.emit('error', {message:"stream not readable"}); }; var output_base64 = function(data, callback) { var loops = Math.ceil(data.length / MIMECHUNK); var loop = 0; while(loop < loops) { output(data.substring(MIMECHUNK * loop, MIMECHUNK * (loop + 1)) + CRLF); loop++; } if(callback) callback(); }; var output_text = function(message) { var data = []; data = data.concat(["Content-Type:", message.content, CRLF, "Content-Transfer-Encoding: 7bit", CRLF]); data = data.concat(["Content-Disposition: inline", CRLF, CRLF]); data = data.concat([message.text || "", CRLF, CRLF]); output(data.join('')); }; var output_alternative = function(message, callback) { var data = [], boundary = generate_boundary(); data = data.concat(["Content-Type: multipart/alternative; boundary=\"", boundary, "\"", CRLF, CRLF]); data = data.concat(["--", boundary, CRLF]); output(data.join('')); output_text(message); output(["--", boundary, CRLF].join('')); var finish = function() { output([CRLF, "--", boundary, "--", CRLF, CRLF].join('')); callback(); }; if(message.alternative.related) { output_related(message.alternative, finish); } else { output_attachment(message.alternative, finish); } }; var output_related = function(message, callback) { var data = [], boundary = generate_boundary(); data = data.concat(["Content-Type: multipart/related; boundary=\"", boundary, "\"", CRLF, CRLF]); data = data.concat(["--", boundary, CRLF]); output(data.join('')); output_attachment(message, function() { output_message(boundary, message.related, 0, function() { output([CRLF, "--", boundary, "--", CRLF, CRLF].join('')); callback(); }); }); }; var output_header_data = function() { if(self.message.attachments.length || self.message.alternative) { output("MIME-Version: 1.0" + CRLF); output_mixed(); } else // you only have a text message! { output_text(self.message); close(); } }; var output_header = function() { var data = []; for(var header in self.message.header) { // do not output BCC in the headers (regex) nor custom Object.prototype functions... if(!(/bcc/i.test(header)) && self.message.header.hasOwnProperty (header)) data = data.concat([fix_header_name_case(header), ": ", self.message.header[header], CRLF]); } output(data.join('')); output_header_data(); }; var output = function(data, callback, args) { var bytes = Buffer.byteLength(data); // can we buffer the data? if(bytes + self.bufferIndex < self.buffer.length) { self.buffer.write(data, self.bufferIndex); self.bufferIndex += bytes; if(callback) callback.apply(null, args); } // we can't buffer the data, so ship it out! else if(bytes > self.buffer.length) { if(self.bufferIndex) { self.emit('data', self.buffer.toString("utf-8", 0, self.bufferIndex)); self.bufferIndex = 0; } var loops = Math.ceil(data.length / self.buffer.length); var loop = 0; while(loop < loops) { self.emit('data', data.substring(self.buffer.length*loop, self.buffer.length*(loop + 1))); loop++; } } else // we need to clean out the buffer, it is getting full { if(!self.paused) { self.emit('data', self.buffer.toString("utf-8", 0, self.bufferIndex)); self.buffer.write(data, 0); self.bufferIndex = bytes; // we could get paused after emitting data... if(self.paused) { self.once("resume", function() { callback.apply(null, args); }); } else if(callback) { callback.apply(null, args); } } else // we can't empty out the buffer, so let's wait till we resume before adding to it { self.once("resume", function() { output(data, callback, args); }); } } }; var close = function(err) { if(err) { self.emit("error", err); } else { self.emit('data', self.buffer.toString("utf-8", 0, self.bufferIndex)); self.emit('end'); } self.buffer = null; self.bufferIndex = 0; self.readable = false; self.removeAllListeners("resume"); self.removeAllListeners("pause"); self.removeAllListeners("error"); self.removeAllListeners("data"); self.removeAllListeners("end"); }; self.once("destroy", close); process.nextTick(output_header); };
/** * * Constructor is a single global object * * Available properties for configuration object: * * opts.channel //name of the channel, with or without leading '#' (defaults to #test) * opts.nick //nick to use (defaults to "robot_SOMENUMBER") * opts.serverAddress //address of irc server (defaults to localhost) * opts.serverPort //port of irc server (defaults to 6667) * opts.mode //should be either 'readable' or 'writable' as needed * opts.ircOpts //special options passed to irc module. see irc module documentation at https://node-irc.readthedocs.org/en/latest/API.html#irc.Client (and note that if channels and port fields are specified here, they will instead be overwritten with the values above) * * @param {Object} opts The regular expression configuration. * */ function SimpleIRCStream(opts) { this.verbose = false; // name of the application, defined in package.json, used for errors this._appName = require('./package').name this._version = require('./package').version this._errorPrefix = this._appName + ': ' this._paused = this._ended = this._destroyed = false this._buffer = '' Stream.call(this) if (!opts) opts = {} if (!opts.serverPort) opts.serverPort = 6667 this.serverPort = opts.serverPort if(!opts.serverAddress) opts.serverAddress = "localhost" this.serverAddress = opts.serverAddress if(opts.channel) this.channel = opts.channel else this.channel = "test" //prepend with # if needed if(this.channel[0] !== '#') this.channel = '#' + this.channel if(opts.nick) this.nick = opts.nick else{ var botNum = Math.floor((Math.random()*10000)) this.nick = "robot_" + botNum } if(opts.mode && opts.mode.toLowerCase() === 'readable'){ this._mode = 'readable' this.writable = false this.readable = true }else if(opts.mode && opts.mode.toLowerCase() === 'writable'){ this._mode = 'writable' this.writable = true this.readable = false }else{ //TODO how best to handle? There's probably a better way. this.writable = false this.readable = false console.log("ERROR: mode must be readable or writable") return null } this.ircOpts = {} if(opts.ircOpts) this.ircOpts = opts.ircOpts this.ircOpts.channels = [this.channel] //not working for some reason? will join() instead. this.ircOpts.port = this.serverPort //actually connect now this.ircClient = new irc.Client(this.serverAddress, this.nick, this.ircOpts); var self = this; this.ircClient.addListener('registered', function(){ //now that you have your connection, you can do your other needed stuff. self.ircClient.join(self.channel) }) //set up the listner, will emit events here if desired. if(this._mode === 'readable'){ this.ircClient.addListener('message'+this.channel, function (from, message) { //TODO replace with a useful listener console.log(from + ' => ' + this.channel + ': ' + message); this.emit('message', message) }) } //set up a listener for errors (from the server, etc) this.ircClient.addListener('error', function(message) { console.log('error: ', message);//TODO better handling }) return this }
function SerialPort(path, options, openImmediately, callback) { var args = Array.prototype.slice.call(arguments); callback = args.pop(); if (typeof callback !== 'function') { callback = null; } options = (typeof options !== 'function') && options || {}; if (openImmediately === undefined || openImmediately === null) { openImmediately = true; } stream.Stream.call(this); callback = callback || function (err) { if (err) { if (this._events.error) { this.emit('error', err); } else { factory.emit('error', err); } } }.bind(this); if (!path) { return callback(new Error('Invalid port specified: ' + path)); } this.path = path; var correctedOptions = correctOptions(options); var settings = assign({}, defaultSettings, correctedOptions); if (DATABITS.indexOf(settings.dataBits) === -1) { return callback(new Error('Invalid "databits": ' + settings.dataBits)); } if (STOPBITS.indexOf(settings.stopBits) === -1) { return callback(new Error('Invalid "stopbits": ' + settings.stopbits)); } if (PARITY.indexOf(settings.parity) === -1) { return callback(new Error('Invalid "parity": ' + settings.parity)); } var fc = settings.flowControl; if (fc === true) { // Why!? settings.rtscts = true; } else if (Array.isArray(fc)) { for (var i = fc.length - 1; i >= 0; i--) { var fcSetting = fc[i].toLowerCase(); if (FLOWCONTROLS.indexOf(fcSetting) > -1) { settings[fcSetting] = true; } else { return callback(new Error('Invalid flowControl option: ' + fcSetting)); } } } // TODO remove this option settings.dataCallback = options.dataCallback || function (data) { settings.parser(this, data); }.bind(this); // TODO remove this option settings.disconnectedCallback = options.disconnectedCallback || function (err) { if (this.closing) { return; } if (!err) { err = new Error('Disconnected'); } this.emit('disconnect', err); }.bind(this); this.fd = null; this.paused = true; this.opening = false; this.closing = false; if (process.platform !== 'win32') { this.bufferSize = settings.bufferSize; this.readable = true; this.reading = false; } this.options = settings; if (openImmediately) { process.nextTick(function () { this.open(callback); }.bind(this)); } }
function Readable () { this.readable = true; stream.Stream.call(this); }
Nockstream = function(opts) { MockStream.call(this, [opts]); Stream.call(this); this.streamBuffer = new Buffer(opts.streamString); this.streamLength = this.streamBuffer.length; };
function Subscriber () { stream.Stream.call(this); this.writeable = true; }
function PrettyStream(opts){ var options = {}; if (opts){ Object.keys(opts).forEach(function(key){ options[key] = { value: opts[key], enumerable: true, writable: true, configurable: true }; }); } var config = Object.create(defaultOptions, options); this.readable = true; this.writable = true; Stream.call(this); function stylize(str, color) { if (!str){ return ''; } if (!config.useColor){ return str; } if (!color){ color = 'white'; } var codes = colors[color]; if (codes) { return '\x1B[' + codes[0] + 'm' + str + '\x1B[' + codes[1] + 'm'; } return str; } function indent(s) { return ' ' + s.split(/\r?\n/).join('\n '); } function extractTime(rec){ var time = (typeof rec.time === 'object') ? rec.time.toISOString() : rec.time; if ((config.mode === 'short' || config.mode === 'dev') && time[10] == 'T') { return stylize(time.substr(11)); } return stylize(time); } function extractName(rec){ var name = rec.name; if (rec.component) { name += '/' + rec.component; } if (config.mode !== 'short' && config.mode !== 'dev'){ name += '/' + rec.pid; } return name; } function extractLevel(rec){ var level = (upperPaddedNameFromLevel[rec.level] || 'LVL' + rec.level); return stylize(level, colorFromLevel[rec.level]); } function extractSrc(rec){ var src = ''; if (rec.src && rec.src.file) { if (rec.src.func) { src = format('(%s:%d in %s)', rec.src.file, rec.src.line, rec.src.func); } else { src = format('(%s:%d)', rec.src.file, rec.src.line); } } return stylize(src, 'green'); } function extractHost(rec){ return rec.hostname || '<no-hostname>'; } function isSingleLineMsg(rec){ return rec.msg.indexOf('\n') === -1; } function extractMsg(rec){ return stylize(rec.msg, 'cyan'); } function extractReqDetail(rec){ if (rec.req && typeof (rec.req) === 'object') { var req = rec.req; var headers = req.headers; var str = format('%s %s HTTP/%s%s%s', req.method, req.url, req.httpVersion || '1.1', (req.remoteAddress ? "\nremote: " + req.remoteAddress + ":" + req.remotePort : ""), (headers ? '\n' + Object.keys(headers).map(function (h) { return h + ': ' + headers[h]; }).join('\n') : '') ); if (req.body) { str += '\n\n' + (typeof (req.body) === 'object' ? JSON_stringify(req.body, null, 2) : req.body); } if (req.trailers && Object.keys(req.trailers) > 0) { str += '\n' + Object.keys(req.trailers).map(function (t) { return t + ': ' + req.trailers[t]; }).join('\n'); } var skip = ['headers', 'url', 'httpVersion', 'body', 'trailers', 'method', 'remoteAddress', 'remotePort']; var extras = {}; Object.keys(req).forEach(function (k) { if (skip.indexOf(k) === -1){ extras['req.' + k] = req[k]; } }); return { details: [str], extras: extras }; } } function genericRes(res) { var s = ''; if (res.statusCode) { s += format('HTTP/1.1 %s %s\n', res.statusCode, http.STATUS_CODES[res.statusCode]); } // Handle `res.header` or `res.headers` as either a string or // and object of header key/value pairs. Prefer `res.header` if set // (TODO: Why? I don't recall. Typical of restify serializer? // Typical JSON.stringify of a core node HttpResponse?) var headers; if (res.header !== undefined) { headers = res.header; } else if (res.headers !== undefined) { headers = res.headers; } if (!headers) { // pass through } else if (typeof(headers) === 'string') { s += headers.trimRight(); } else { s += Object.keys(headers).map( function (h) { return h + ': ' + headers[h]; }).join('\n'); } if (res.body) { s += '\n\n' + (typeof (res.body) === 'object' ? JSON_stringify(res.body, null, 2) : res.body); } if (res.trailer) { s += '\n' + res.trailer; } var skip = ['header', 'statusCode', 'headers', 'body', 'trailer']; var extras = {}; Object.keys(res).forEach(function (k) { if (skip.indexOf(k) === -1){ extras['res.' + k] = res[k]; } }); return { details: [s], extras: extras }; } function extractResDetail(rec){ if (rec.res && typeof (rec.res) === 'object') { return genericRes(rec.res); } } function extractClientReqDetail(rec){ if (rec.client_req && typeof (rec.client_req) === 'object') { var client_req = rec.client_req; var headers = client_req.headers; var hostHeaderLine = ''; var s = ''; if (client_req.address) { hostHeaderLine = 'Host: ' + client_req.address; if (client_req.port) { hostHeaderLine += ':' + client_req.port; } hostHeaderLine += '\n'; } s += format('%s %s HTTP/%s\n%s%s', client_req.method, client_req.url, client_req.httpVersion || '1.1', hostHeaderLine, (headers ? Object.keys(headers).map( function (h) { return h + ': ' + headers[h]; }).join('\n') : '')); if (client_req.body) { s += '\n\n' + (typeof (client_req.body) === 'object' ? JSON_stringify(client_req.body, null, 2) : client_req.body); } var skip = ['headers', 'url', 'httpVersion', 'body', 'trailers', 'method', 'remoteAddress', 'remotePort']; var extras = {}; Object.keys(client_req).forEach(function (k) { if (skip.indexOf(k) === -1){ extras['client_req.' + k] = client_req[k]; } }); return { details: [s], extras: extras }; } } function extractClientResDetail(rec){ if (rec.client_res && typeof (rec.client_res) === 'object') { return genericRes(rec.client_res); } } function extractError(rec){ if (rec.err && rec.err.stack) { return rec.err.stack; } } function extractCustomDetails(rec){ var skip = ['name', 'hostname', 'pid', 'level', 'component', 'msg', 'time', 'v', 'src', 'err', 'client_req', 'client_res', 'req', 'res']; var details = []; var extras = {}; Object.keys(rec).forEach(function(key) { if (skip.indexOf(key) === -1){ var value = rec[key]; if (typeof value === 'undefined') value = ''; var stringified = false; if (typeof value !== 'string') { value = JSON_stringify(value, null, 2); stringified = true; } if (value.indexOf('\n') !== -1 || value.length > 50) { details.push(key + ': ' + value); } else if (!stringified && (value.indexOf(' ') != -1 || value.length === 0)){ extras[key] = JSON_stringify(value); } else { extras[key] = value; } } }); return { details: details, extras: extras }; } function applyDetails(results, details, extras){ if (results){ results.details.forEach(function(d){ details.push(indent(d)); }); Object.keys(results.extras).forEach(function(k){ extras.push(k + '=' + results.extras[k]); }); } } this.formatRecord = function formatRecord(rec){ var details = []; var extras = []; var time = extractTime(rec); var level = extractLevel(rec); var name = extractName(rec); var host = extractHost(rec); var src = extractSrc(rec); var msg = isSingleLineMsg(rec) ? extractMsg(rec) : ''; if (!msg){ details.push(indent(extractMsg(rec))); } var error = extractError(rec); if (error){ details.push(indent(error)); } if (rec.req){ applyDetails(extractReqDetail(rec), details, extras); } if (rec.res){ applyDetails(extractResDetail(rec), details, extras); } if (rec.client_req){ applyDetails(extractClientReqDetail(rec), details, extras); } if (rec.client_res){ applyDetails(extractClientResDetail(rec), details, extras); } applyDetails(extractCustomDetails(rec), details, extras); extras = stylize( (extras.length ? ' (' + extras.join(', ') + ')' : ''), 'grey'); details = stylize( (details.length ? details.join('\n --\n') + '\n' : ''), 'grey'); if (config.mode === 'long'){ return format('[%s] %s: %s on %s%s: %s%s\n%s', time, level, name, host, src, msg, extras, details); } if (config.mode === 'short'){ return format('[%s] %s %s: %s%s\n%s', time, level, name, msg, extras, details); } if (config.mode === 'dev'){ return format('%s %s %s %s: %s%s\n%s', time, level, name, src, msg, extras, details); } }; }
function Request(options, connection) { stream.Stream.call(this); this._options = options; this._connection = connection; this.push(); }
var Channel = function(conn, topic, channels) { this.conn = conn; this.topic = topic; this.channels = channels; stream.Stream.call(this); };
function File (options) { stream.Stream.call(this) this.writable = true this.readable = true this.buffers = [] var self = this if (typeof options === 'string') options = {path:options} if (!options.index) options.index = 'index.html' self.writable = (typeof options.writable === "undefined") ? true : options.writable self.readable = (typeof options.readable === "undefined") ? true : options.readable self.path = options.path self.index = options.index self.on('pipe', function (src) { this.src = src }) this.buffering = true this.mimetype = options.mimetype || mime.getType(this.path.slice(this.path.lastIndexOf('.')+1)) var stopBuffering = function () { self.buffering = false while (self.buffers.length) { self.emit('data', self.buffers.shift()) } if (self.ended) self.emit('end') } fs.stat(options.path, function (err, stats) { var finish = function (err, stats) { self.stat = stats if (err && err.code === 'ENOENT' && !self.dest && !self.src) self.src = self.path if (err && !self.dest && !self.src) return self.emit('error', err) if (err && self.dest && !self.dest.writeHead) return self.emit('error', err) // See if writes are disabled if (self.src && self.src.method && !self.writable && self.dest.writeHead && (self.src.method === 'PUT' || self.src.method === 'POST')) { self.dest.writeHead(405, {'content-type':'text/plain'}) self.dest.end(self.src.method+' Not Allowed') return } if (!err) { self.etag = crypto.createHash('md5').update(stats.ino+'/'+stats.mtime+'/'+stats.size).digest("hex") self.lastmodified = rfc822.getRFC822Date(stats.mtime) } process.nextTick(function () { stopBuffering() }) // 404 and 500 if ( err && self.dest && self.dest.writeHead && // We have an error object and dest is an HTTP response ( // Either we have a source and it's a GET/HEAD or we don't have a src (self.src && (self.src.method == 'GET' || self.src.method === 'HEAD')) || (!self.src) ) ) { if (err.code === 'ENOENT') { self.dest.statusCode = 404 self.dest.end('Not Found') } else { self.dest.statusCode = 500 self.dest.end(err.message) } return } // Source is an HTTP Server Request if (self.src && (self.src.method === 'GET' || self.src.method === 'HEAD') && self.dest) { if (self.dest.setHeader) { self.dest.setHeader('content-type', self.mimetype) self.dest.setHeader('etag', self.etag) self.dest.setHeader('last-modified', self.lastmodified) } if (self.dest.writeHead) { if (self.src && self.src.headers) { if (self.src.headers['if-none-match'] === self.etag || // Lazy last-modifed matching but it's faster than parsing Datetime self.src.headers['if-modified-since'] === self.lastmodified) { self.dest.statusCode = 304 self.dest.end() return } } // We're going to return the whole file self.dest.statusCode = 200 self.dest.setHeader('content-length', stats.size) } else { // Destination is not an HTTP response, GET and HEAD method are not allowed return } if (self.src.method !== 'HEAD') { fs.createReadStream(self.path).pipe(self.dest) } return } if (self.src && (self.src.method === 'PUT' || self.src.method === 'POST')) { if (!err) { // TODO handle overwrite case return } stream.Stream.prototype.pipe.call(self, fs.createWriteStream(self.path)) if (self.dest && self.dest.writeHead) { self.on('end', function () { self.dest.statusCode = 201 self.dest.setHeader('content-length', 0) self.dest.end() }) } return } // Desination is an HTTP response, we already handled 404 and 500 if (self.dest && self.dest.writeHead) { self.dest.statusCode = 200 self.dest.setHeader('content-type', self.mimetype) self.dest.setHeader('etag', self.etag) self.dest.setHeader('last-modified', self.lastmodified) self.dest.setHeader('content-length', stats.size) fs.createReadStream(self.path).pipe(self.dest) return } // Destination is not an HTTP request if (self.src && !self.dest) { stream.Stream.prototype.pipe.call(self, fs.createWriteStream(self.path)) } else if (self.dest && !self.src) { fs.createReadStream(self.path).pipe(self.dest) } } if (!err && stats.isDirectory()) { self.path = path.join(self.path, self.index) self.mimetype = mime.getType(self.path.slice(self.path.lastIndexOf('.')+1)) fs.stat(self.path, finish) return } else { finish(err, stats) } if (!self.src && !self.dest) { if (self.buffers.length > 0) { stream.Stream.prototype.pipe.call(self, fs.createWriteStream(self.path)) } else if (self.listeners('data').length > 0) { fs.createReadStream(self.path).pipe(self.dest) } else { fs.createReadStream(self.path).pipe(self) } } }) }
///--- API /** * Request is a wrapper over node's http.IncomingMessage object. * * Previous versions of restify just extended the prototype, but that was * problemtic if used in conjunction with other modules that do this as well * (namely express). * * This object exposes all of the properties/events/methods of the standard * Request object, plus some extra goodies. * * @param {Object} options pass in log4js handle and an http.IncomingMessage. * @throws {TypeError} on input error. */ function Request(options) { if (typeof(options) !== 'object') throw new TypeError('options (Object) required'); if (typeof(options.log4js) !== 'object') throw new TypeError('options.log4js (Object) required'); if (typeof(options.request) !== 'object') throw new TypeError('options.request (http.IncomingMessage) required'); Stream.call(this); this.req = options.request; this.log4js = options.log4js; this.log = this.log4js.getLogger('Request'); var id = uuid(); var _url = url.parse(this.req.url); var path = sanitizePath(_url.pathname); var self = this; this.__defineGetter__('connection', function() { return self.req.connection; }); this.__defineGetter__('contentLength', function() { return self.req.headers['content-length']; }); this.__defineGetter__('contentType', function() { var type = self.req.headers['content-type']; // RFC2616 section 7.2.1 if (!type) return 'application/octet-stream'; var index = type.indexOf(';'); if (index === -1) return type; return type.substring(0, index); }); this.__defineGetter__('headers', function() { return self.req.headers; }); this.__defineGetter__('httpVersion', function() { return self.req.httpVersion; }); this.__defineGetter__('httpVersionMajor', function() { return self.req.httpVersionMajor; }); this.__defineGetter__('httpVersionMinor', function() { return self.req.httpVersionMinor; }); this.__defineGetter__('href', function() { return _url.href; }); this.__defineGetter__('id', function() { return id; }); this.__defineGetter__('method', function() { return self.req.method; }); this.__defineGetter__('path', function() { return path; }); this.__defineGetter__('pathname', function() { return path; }); this.__defineGetter__('query', function() { return _url.query; }); this.__defineGetter__('readable', function() { return self.req.readable; }); this.__defineGetter__('requestId', function() { return id; }); this.__defineGetter__('search', function() { return _url.search; }); this.__defineGetter__('secure', function(){ return self.req.connection.encrypted; }); var now = new Date(); this.__defineGetter__('time', function() { return now; }); this.__defineGetter__('trailers', function(){ return self.req.trailers || {}; }); this.__defineGetter__('url', function() { return self.req.url; }); this.__defineGetter__('userAgent', function() { return self.req.headers['user-agent']; }); this.__defineGetter__('version', function() { var headers = self.req.headers; return headers['accept-version'] || headers['x-api-version'] || '*'; }); this.req.on('data', function(chunk) { self.emit('data', chunk); }); this.req.on('end', function() { self.emit('end'); }); this.req.on('error', function(err) { self.emit('error', err); }); this.req.on('close', function() { self.emit('close'); }); }
function SerialPort(path, options, openImmediately, callback) { var self = this; var args = Array.prototype.slice.call(arguments); callback = args.pop(); if (typeof (callback) !== 'function') { callback = null; } options = (typeof options !== 'function') && options || {}; openImmediately = (openImmediately === undefined || openImmediately === null) ? true : openImmediately; stream.Stream.call(this); callback = callback || function (err) { if (err) { if (self._events.error) { self.emit('error', err); } else { factory.emit('error', err); } } }; var err; options.baudRate = options.baudRate || options.baudrate || _options.baudrate; options.dataBits = options.dataBits || options.databits || _options.databits; if (DATABITS.indexOf(options.dataBits) === -1) { err = new Error('Invalid "databits": ' + options.dataBits); callback(err); return; } options.stopBits = options.stopBits || options.stopbits || _options.stopbits; if (STOPBITS.indexOf(options.stopBits) === -1) { err = new Error('Invalid "stopbits": ' + options.stopbits); callback(err); return; } options.parity = options.parity || _options.parity; if (PARITY.indexOf(options.parity) === -1) { err = new Error('Invalid "parity": ' + options.parity); callback(err); return; } if (!path) { err = new Error('Invalid port specified: ' + path); callback(err); return; } // flush defaults, then update with provided details options.rtscts = _options.rtscts; options.xon = _options.xon; options.xoff = _options.xoff; options.xany = _options.xany; if (options.flowControl || options.flowcontrol) { var fc = options.flowControl || options.flowcontrol; if (typeof fc === 'boolean') { options.rtscts = true; } else { fc.forEach(function (flowControl) { var fcup = flowControl.toUpperCase(); var idx = FLOWCONTROLS.indexOf(fcup); if (idx < 0) { var err = new Error('Invalid "flowControl": ' + fcup + ". Valid options: " + FLOWCONTROLS.join(", ")); callback(err); return; } else { // "XON", "XOFF", "XANY", "DTRDTS", "RTSCTS" switch (idx) { case 0: options.xon = true; break; case 1: options.xoff = true; break; case 2: options.xany = true; break; case 3: options.rtscts = true; break; } } }); } } options.bufferSize = options.bufferSize || options.buffersize || _options.buffersize; options.parser = options.parser || _options.parser; options.platformOptions = options.platformOptions || _options.platformOptions; options.dataCallback = options.dataCallback || function (data) { options.parser(self, data); }; options.disconnectedCallback = options.disconnectedCallback || function (err) { if (self.closing) { return; } if (!err) { err = new Error("Disconnected"); } self.emit("disconnect", err); }; if (process.platform !== 'win32') { // All other platforms: this.fd = null; this.paused = true; this.bufferSize = options.bufferSize || 64 * 1024; this.readable = true; this.reading = false; } this.options = options; this.path = path; if (openImmediately) { process.nextTick(function () { self.open(callback); }); } }
function SerialPort (path, options) { options = options || {}; options.__proto__ = _options; if (BAUDRATES.indexOf(options.baudrate) == -1) { throw new Error('Invalid "baudrate": ' + options.baudrate); } if (DATABITS.indexOf(options.databits) == -1) { throw new Error('Invalid "databits": ' + options.databits); } if (STOPBITS.indexOf(options.stopbits) == -1) { throw new Error('Invalid "stopbits": ' + options.stopbits); } if (PARITY.indexOf(options.parity) == -1) { throw new Error('Invalid "parity": ' + options.parity); } if (FLOWCONTROL.indexOf(options.flowcontrol) == -1) { throw new Error('Invalid "flowcontrol": ' + options.flowcontrol); } if (!path) { throw new Error('Invalid port specified: ' + path); } stream.Stream.call(this); var self = this; process.nextTick(function () { options = options || {}; options.baudRate = options.baudRate || options.baudrate || 9600; options.dataBits = options.dataBits || options.databits || 8; options.parity = options.parity || 'none'; options.stopBits = options.stopBits || options.stopbits || 1; options.bufferSize = options.bufferSize || options.buffersize || 100; if (!('flowControl' in options)) { options.flowControl = false; } options.dataCallback = function (data) { options.parser(self, data); }; options.errorCallback = function (err) { self.emit('error', err); }; options.disconnectedCallback = function () { if (self.closing) { return; } self.emit('error', new Error("Disconnected")); self.close(); }; if (process.platform == 'win32') { path = '\\\\.\\' + path; } SerialPortBinding.open(path, options, function (err, fd) { self.fd = fd; if (err) { return self.emit('error', err); } if (process.platform !== 'win32') { self.readStream = fs.createReadStream(path, { bufferSize: options.bufferSize, fd: fd }); self.readStream.on("data", options.dataCallback); self.readStream.on("error", options.errorCallback); self.readStream.on("close", function () { self.close(); }); self.readStream.on("end", function () { self.emit('end'); }); } self.emit('open'); }); }); }
function ArrayFormatter() { Stream.call(this); this.writable = true; this._done = false; this.meta = {}; }
var VMDKStream = function (vmdk) { this.vmdk = vmdk; Stream.call(this); };