base project
This commit is contained in:
141
node_modules/union/lib/buffered-stream.js
generated
vendored
Normal file
141
node_modules/union/lib/buffered-stream.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* buffered-stream.js: A simple(r) Stream which is partially buffered into memory.
|
||||
*
|
||||
* (C) 2010, Mikeal Rogers
|
||||
*
|
||||
* Adapted for Flatiron
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
fs = require('fs'),
|
||||
stream = require('stream'),
|
||||
util = require('util');
|
||||
|
||||
//
|
||||
// ### function BufferedStream (limit)
|
||||
// #### @limit {number} **Optional** Size of the buffer to limit
|
||||
// Constructor function for the BufferedStream object responsible for
|
||||
// maintaining a stream interface which can also persist to memory
|
||||
// temporarily.
|
||||
//
|
||||
|
||||
var BufferedStream = module.exports = function (limit) {
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
if (typeof limit === 'undefined') {
|
||||
limit = Infinity;
|
||||
}
|
||||
|
||||
this.limit = limit;
|
||||
this.size = 0;
|
||||
this.chunks = [];
|
||||
this.writable = true;
|
||||
this.readable = true;
|
||||
this._buffer = true;
|
||||
};
|
||||
|
||||
util.inherits(BufferedStream, stream.Stream);
|
||||
|
||||
Object.defineProperty(BufferedStream.prototype, 'buffer', {
|
||||
get: function () {
|
||||
return this._buffer;
|
||||
},
|
||||
set: function (value) {
|
||||
if (!value && this.chunks) {
|
||||
var self = this;
|
||||
this.chunks.forEach(function (c) { self.emit('data', c) });
|
||||
if (this.ended) this.emit('end');
|
||||
this.size = 0;
|
||||
delete this.chunks;
|
||||
}
|
||||
|
||||
this._buffer = value;
|
||||
}
|
||||
});
|
||||
|
||||
BufferedStream.prototype.pipe = function () {
|
||||
var self = this,
|
||||
dest;
|
||||
|
||||
if (self.resume) {
|
||||
self.resume();
|
||||
}
|
||||
|
||||
dest = stream.Stream.prototype.pipe.apply(self, arguments);
|
||||
|
||||
//
|
||||
// just incase you are piping to two streams, do not emit data twice.
|
||||
// note: you can pipe twice, but you need to pipe both streams in the same tick.
|
||||
// (this is normal for streams)
|
||||
//
|
||||
if (this.piped) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
process.nextTick(function () {
|
||||
if (self.chunks) {
|
||||
self.chunks.forEach(function (c) { self.emit('data', c) });
|
||||
self.size = 0;
|
||||
delete self.chunks;
|
||||
}
|
||||
|
||||
if (!self.readable) {
|
||||
if (self.ended) {
|
||||
self.emit('end');
|
||||
}
|
||||
else if (self.closed) {
|
||||
self.emit('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.piped = true;
|
||||
|
||||
return dest;
|
||||
};
|
||||
|
||||
BufferedStream.prototype.write = function (chunk) {
|
||||
if (!this.chunks || this.piped) {
|
||||
this.emit('data', chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
this.chunks.push(chunk);
|
||||
this.size += chunk.length;
|
||||
if (this.limit < this.size) {
|
||||
this.pause();
|
||||
}
|
||||
};
|
||||
|
||||
BufferedStream.prototype.end = function () {
|
||||
this.readable = false;
|
||||
this.ended = true;
|
||||
this.emit('end');
|
||||
};
|
||||
|
||||
BufferedStream.prototype.destroy = function () {
|
||||
this.readable = false;
|
||||
this.writable = false;
|
||||
delete this.chunks;
|
||||
};
|
||||
|
||||
BufferedStream.prototype.close = function () {
|
||||
this.readable = false;
|
||||
this.closed = true;
|
||||
};
|
||||
|
||||
if (!stream.Stream.prototype.pause) {
|
||||
BufferedStream.prototype.pause = function () {
|
||||
this.emit('pause');
|
||||
};
|
||||
}
|
||||
|
||||
if (!stream.Stream.prototype.resume) {
|
||||
BufferedStream.prototype.resume = function () {
|
||||
this.emit('resume');
|
||||
};
|
||||
}
|
||||
|
108
node_modules/union/lib/core.js
generated
vendored
Normal file
108
node_modules/union/lib/core.js
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* core.js: Core functionality for the Flatiron HTTP (with SPDY support) plugin.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var http = require('http'),
|
||||
https = require('https'),
|
||||
fs = require('fs'),
|
||||
stream = require('stream'),
|
||||
HttpStream = require('./http-stream'),
|
||||
RoutingStream = require('./routing-stream');
|
||||
|
||||
var core = exports;
|
||||
|
||||
core.createServer = function (options) {
|
||||
var isArray = Array.isArray(options.after),
|
||||
credentials;
|
||||
|
||||
if (!options) {
|
||||
throw new Error('options is required to create a server');
|
||||
}
|
||||
|
||||
function requestHandler(req, res) {
|
||||
var routingStream = new RoutingStream({
|
||||
before: options.before,
|
||||
buffer: options.buffer,
|
||||
//
|
||||
// Remark: without new after is a huge memory leak that
|
||||
// pipes to every single open connection
|
||||
//
|
||||
after: isArray && options.after.map(function (After) {
|
||||
return new After;
|
||||
}),
|
||||
request: req,
|
||||
response: res,
|
||||
limit: options.limit,
|
||||
headers: options.headers
|
||||
});
|
||||
|
||||
routingStream.on('error', function (err) {
|
||||
var fn = options.onError || core.errorHandler;
|
||||
fn(err, routingStream, routingStream.target, function () {
|
||||
routingStream.target.emit('next');
|
||||
});
|
||||
});
|
||||
|
||||
req.pipe(routingStream);
|
||||
}
|
||||
|
||||
//
|
||||
// both https and spdy requires same params
|
||||
//
|
||||
if (options.https || options.spdy) {
|
||||
if (options.https && options.spdy) {
|
||||
throw new Error('You shouldn\'t be using https and spdy simultaneously.');
|
||||
}
|
||||
|
||||
var serverOptions,
|
||||
credentials,
|
||||
key = !options.spdy
|
||||
? 'https'
|
||||
: 'spdy';
|
||||
|
||||
serverOptions = options[key];
|
||||
if (!serverOptions.key || !serverOptions.cert) {
|
||||
throw new Error('Both options.' + key + '.`key` and options.' + key + '.`cert` are required.');
|
||||
}
|
||||
|
||||
credentials = {
|
||||
key: fs.readFileSync(serverOptions.key),
|
||||
cert: fs.readFileSync(serverOptions.cert)
|
||||
};
|
||||
|
||||
if (serverOptions.ca) {
|
||||
serverOptions.ca = !Array.isArray(serverOptions.ca)
|
||||
? [serverOptions.ca]
|
||||
: serverOptions.ca
|
||||
|
||||
credentials.ca = serverOptions.ca.map(function (ca) {
|
||||
return fs.readFileSync(ca);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.spdy) {
|
||||
// spdy is optional so we require module here rather than on top
|
||||
var spdy = require('spdy');
|
||||
return spdy.createServer(credentials, requestHandler);
|
||||
}
|
||||
|
||||
return https.createServer(credentials, requestHandler);
|
||||
}
|
||||
|
||||
return http.createServer(requestHandler);
|
||||
};
|
||||
|
||||
core.errorHandler = function error(err, req, res) {
|
||||
if (err) {
|
||||
(this.res || res).writeHead(err.status || 500, err.headers || { "Content-Type": "text/plain" });
|
||||
(this.res || res).end(err.message + "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
(this.res || res).writeHead(404, {"Content-Type": "text/plain"});
|
||||
(this.res || res).end("Not Found\n");
|
||||
};
|
52
node_modules/union/lib/http-stream.js
generated
vendored
Normal file
52
node_modules/union/lib/http-stream.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* http-stream.js: Idomatic buffered stream which pipes additional HTTP information.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var url = require('url'),
|
||||
util = require('util'),
|
||||
qs = require('qs'),
|
||||
BufferedStream = require('./buffered-stream');
|
||||
|
||||
var HttpStream = module.exports = function (options) {
|
||||
options = options || {};
|
||||
BufferedStream.call(this, options.limit);
|
||||
|
||||
if (options.buffer === false) {
|
||||
this.buffer = false;
|
||||
}
|
||||
|
||||
this.on('pipe', this.pipeState);
|
||||
};
|
||||
|
||||
util.inherits(HttpStream, BufferedStream);
|
||||
|
||||
//
|
||||
// ### function pipeState (source)
|
||||
// #### @source {ServerRequest|HttpStream} Source stream piping to this instance
|
||||
// Pipes additional HTTP metadata from the `source` HTTP stream (either concrete or
|
||||
// abstract) to this instance. e.g. url, headers, query, etc.
|
||||
//
|
||||
// Remark: Is there anything else we wish to pipe?
|
||||
//
|
||||
HttpStream.prototype.pipeState = function (source) {
|
||||
this.headers = source.headers;
|
||||
this.trailers = source.trailers;
|
||||
this.method = source.method;
|
||||
|
||||
if (source.url) {
|
||||
this.url = this.originalUrl = source.url;
|
||||
}
|
||||
|
||||
if (source.query) {
|
||||
this.query = source.query;
|
||||
}
|
||||
else if (source.url) {
|
||||
this.query = ~source.url.indexOf('?')
|
||||
? qs.parse(url.parse(source.url).query)
|
||||
: {};
|
||||
}
|
||||
};
|
24
node_modules/union/lib/index.js
generated
vendored
Normal file
24
node_modules/union/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* index.js: Top-level plugin exposing HTTP features in flatiron
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var union = exports;
|
||||
|
||||
//
|
||||
// Expose version information
|
||||
//
|
||||
exports.version = require('../package.json').version;
|
||||
|
||||
//
|
||||
// Expose core union components
|
||||
//
|
||||
union.BufferedStream = require('./buffered-stream');
|
||||
union.HttpStream = require('./http-stream');
|
||||
union.ResponseStream = require('./response-stream');
|
||||
union.RoutingStream = require('./routing-stream');
|
||||
union.createServer = require('./core').createServer;
|
||||
union.errorHandler = require('./core').errorHandler;
|
58
node_modules/union/lib/request-stream.js
generated
vendored
Normal file
58
node_modules/union/lib/request-stream.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* http-stream.js: Idomatic buffered stream which pipes additional HTTP information.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var url = require('url'),
|
||||
util = require('util'),
|
||||
qs = require('qs'),
|
||||
HttpStream = require('./http-stream');
|
||||
|
||||
var RequestStream = module.exports = function (options) {
|
||||
options = options || {};
|
||||
HttpStream.call(this, options);
|
||||
|
||||
this.on('pipe', this.pipeRequest);
|
||||
this.request = options.request;
|
||||
};
|
||||
|
||||
util.inherits(RequestStream, HttpStream);
|
||||
|
||||
//
|
||||
// ### function pipeRequest (source)
|
||||
// #### @source {ServerRequest|HttpStream} Source stream piping to this instance
|
||||
// Pipes additional HTTP request metadata from the `source` HTTP stream (either concrete or
|
||||
// abstract) to this instance. e.g. url, headers, query, etc.
|
||||
//
|
||||
// Remark: Is there anything else we wish to pipe?
|
||||
//
|
||||
RequestStream.prototype.pipeRequest = function (source) {
|
||||
this.url = this.originalUrl = source.url;
|
||||
this.method = source.method;
|
||||
this.httpVersion = source.httpVersion;
|
||||
this.httpVersionMajor = source.httpVersionMajor;
|
||||
this.httpVersionMinor = source.httpVersionMinor;
|
||||
this.setEncoding = source.setEncoding;
|
||||
this.connection = source.connection;
|
||||
this.socket = source.socket;
|
||||
|
||||
if (source.query) {
|
||||
this.query = source.query;
|
||||
}
|
||||
else {
|
||||
this.query = ~source.url.indexOf('?')
|
||||
? qs.parse(url.parse(source.url).query)
|
||||
: {};
|
||||
}
|
||||
};
|
||||
|
||||
// http.serverRequest methods
|
||||
['setEncoding'].forEach(function (method) {
|
||||
RequestStream.prototype[method] = function () {
|
||||
return this.request[method].apply(this.request, arguments);
|
||||
};
|
||||
});
|
||||
|
203
node_modules/union/lib/response-stream.js
generated
vendored
Normal file
203
node_modules/union/lib/response-stream.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* response-stream.js: A Stream focused on writing any relevant information to
|
||||
* a raw http.ServerResponse object.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
HttpStream = require('./http-stream');
|
||||
|
||||
var STATUS_CODES = require('http').STATUS_CODES;
|
||||
|
||||
//
|
||||
// ### function ResponseStream (options)
|
||||
//
|
||||
//
|
||||
var ResponseStream = module.exports = function (options) {
|
||||
var self = this,
|
||||
key;
|
||||
|
||||
options = options || {};
|
||||
HttpStream.call(this, options);
|
||||
|
||||
this.writeable = true;
|
||||
this.response = options.response;
|
||||
|
||||
if (options.headers) {
|
||||
for (key in options.headers) {
|
||||
this.response.setHeader(key, options.headers[key]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Proxy `statusCode` changes to the actual `response.statusCode`.
|
||||
//
|
||||
Object.defineProperty(this, 'statusCode', {
|
||||
get: function () {
|
||||
return self.response.statusCode;
|
||||
},
|
||||
set: function (value) {
|
||||
self.response.statusCode = value;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
if (this.response) {
|
||||
this._headers = this.response._headers = this.response._headers || {};
|
||||
|
||||
// Patch to node core
|
||||
this.response._headerNames = this.response._headerNames || {};
|
||||
|
||||
//
|
||||
// Proxy to emit "header" event
|
||||
//
|
||||
this._renderHeaders = this.response._renderHeaders;
|
||||
this.response._renderHeaders = function () {
|
||||
if (!self._emittedHeader) {
|
||||
self._emittedHeader = true;
|
||||
self.headerSent = true;
|
||||
self._header = true;
|
||||
self.emit('header');
|
||||
}
|
||||
|
||||
return self._renderHeaders.call(self.response);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
util.inherits(ResponseStream, HttpStream);
|
||||
|
||||
ResponseStream.prototype.writeHead = function (statusCode, statusMessage, headers) {
|
||||
if (typeof statusMessage === 'string') {
|
||||
this.response.statusMessage = statusMessage;
|
||||
} else {
|
||||
this.response.statusMessage = this.response.statusMessage
|
||||
|| STATUS_CODES[statusCode] || 'unknown';
|
||||
headers = statusMessage;
|
||||
}
|
||||
|
||||
this.response.statusCode = statusCode;
|
||||
|
||||
if (headers) {
|
||||
var keys = Object.keys(headers);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var k = keys[i];
|
||||
if (k) this.response.setHeader(k, headers[k]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Create pass-thru for the necessary
|
||||
// `http.ServerResponse` methods.
|
||||
//
|
||||
['setHeader', 'getHeader', 'removeHeader', '_implicitHeader', 'addTrailers'].forEach(function (method) {
|
||||
ResponseStream.prototype[method] = function () {
|
||||
return this.response[method].apply(this.response, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
ResponseStream.prototype.json = function (obj) {
|
||||
if (!this.response.writable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof obj === 'number') {
|
||||
this.response.statusCode = obj;
|
||||
obj = arguments[1];
|
||||
}
|
||||
|
||||
this.modified = true;
|
||||
|
||||
if (!this.response._header && this.response.getHeader('content-type') !== 'application/json') {
|
||||
this.response.setHeader('content-type', 'application/json');
|
||||
}
|
||||
|
||||
this.end(obj ? JSON.stringify(obj) : '');
|
||||
};
|
||||
|
||||
ResponseStream.prototype.html = function (str) {
|
||||
if (!this.response.writable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof str === 'number') {
|
||||
this.response.statusCode = str;
|
||||
str = arguments[1];
|
||||
}
|
||||
|
||||
this.modified = true;
|
||||
|
||||
if (!this.response._header && this.response.getHeader('content-type') !== 'text/html') {
|
||||
this.response.setHeader('content-type', 'text/html');
|
||||
}
|
||||
|
||||
this.end(str ? str: '');
|
||||
};
|
||||
|
||||
ResponseStream.prototype.text = function (str) {
|
||||
if (!this.response.writable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof str === 'number') {
|
||||
this.response.statusCode = str;
|
||||
str = arguments[1];
|
||||
}
|
||||
|
||||
this.modified = true;
|
||||
|
||||
if (!this.response._header && this.response.getHeader('content-type') !== 'text/plain') {
|
||||
this.response.setHeader('content-type', 'text/plain');
|
||||
}
|
||||
|
||||
this.end(str ? str: '');
|
||||
};
|
||||
|
||||
ResponseStream.prototype.end = function (data) {
|
||||
if (data && this.writable) {
|
||||
this.emit('data', data);
|
||||
}
|
||||
|
||||
this.modified = true;
|
||||
this.emit('end');
|
||||
};
|
||||
|
||||
ResponseStream.prototype.pipe = function () {
|
||||
var self = this,
|
||||
dest;
|
||||
|
||||
self.dest = dest = HttpStream.prototype.pipe.apply(self, arguments);
|
||||
|
||||
dest.on('drain', function() {
|
||||
self.emit('drain')
|
||||
})
|
||||
return dest;
|
||||
};
|
||||
|
||||
ResponseStream.prototype.write = function (data) {
|
||||
this.modified = true;
|
||||
|
||||
if (this.writable) {
|
||||
return this.dest.write(data);
|
||||
}
|
||||
};
|
||||
|
||||
ResponseStream.prototype.redirect = function (path, status) {
|
||||
var url = '';
|
||||
|
||||
if (~path.indexOf('://')) {
|
||||
url = path;
|
||||
} else {
|
||||
url += this.req.connection.encrypted ? 'https://' : 'http://';
|
||||
url += this.req.headers.host;
|
||||
url += (path[0] === '/') ? path : '/' + path;
|
||||
}
|
||||
|
||||
this.res.writeHead(status || 302, { 'Location': url });
|
||||
this.end();
|
||||
};
|
126
node_modules/union/lib/routing-stream.js
generated
vendored
Normal file
126
node_modules/union/lib/routing-stream.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* routing-stream.js: A Stream focused on connecting an arbitrary RequestStream and
|
||||
* ResponseStream through a given Router.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins & the Contributors
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
union = require('./index'),
|
||||
RequestStream = require('./request-stream'),
|
||||
ResponseStream = require('./response-stream');
|
||||
|
||||
//
|
||||
// ### function RoutingStream (options)
|
||||
//
|
||||
//
|
||||
var RoutingStream = module.exports = function (options) {
|
||||
options = options || {};
|
||||
RequestStream.call(this, options);
|
||||
|
||||
this.before = options.before || [];
|
||||
this.after = options.after || [];
|
||||
this.response = options.response || options.res;
|
||||
this.headers = options.headers || {
|
||||
'x-powered-by': 'union ' + union.version
|
||||
};
|
||||
|
||||
this.target = new ResponseStream({
|
||||
response: this.response,
|
||||
headers: this.headers
|
||||
});
|
||||
|
||||
this.once('pipe', this.route);
|
||||
};
|
||||
|
||||
util.inherits(RoutingStream, RequestStream);
|
||||
|
||||
//
|
||||
// Called when this instance is piped to **by another stream**
|
||||
//
|
||||
RoutingStream.prototype.route = function (req) {
|
||||
//
|
||||
// When a `RoutingStream` is piped to:
|
||||
//
|
||||
// 1. Setup the pipe-chain between the `after` middleware, the abstract response
|
||||
// and the concrete response.
|
||||
// 2. Attempt to dispatch to the `before` middleware, which represent things such as
|
||||
// favicon, static files, application routing.
|
||||
// 3. If no match is found then pipe to the 404Stream
|
||||
//
|
||||
var self = this,
|
||||
after,
|
||||
error,
|
||||
i;
|
||||
|
||||
//
|
||||
// Don't allow `this.target` to be writable on HEAD requests
|
||||
//
|
||||
this.target.writable = req.method !== 'HEAD';
|
||||
|
||||
//
|
||||
// 1. Setup the pipe-chain between the `after` middleware, the abstract response
|
||||
// and the concrete response.
|
||||
//
|
||||
after = [this.target].concat(this.after, this.response);
|
||||
for (i = 0; i < after.length - 1; i++) {
|
||||
//
|
||||
// attach req and res to all streams
|
||||
//
|
||||
after[i].req = req;
|
||||
after[i + 1].req = req;
|
||||
after[i].res = this.response;
|
||||
after[i + 1].res = this.response;
|
||||
after[i].pipe(after[i + 1]);
|
||||
|
||||
//
|
||||
// prevent multiple responses and memory leaks
|
||||
//
|
||||
after[i].on('error', this.onError);
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function for dispatching to the 404 stream.
|
||||
//
|
||||
function notFound() {
|
||||
error = new Error('Not found');
|
||||
error.status = 404;
|
||||
self.onError(error);
|
||||
}
|
||||
|
||||
//
|
||||
// 2. Attempt to dispatch to the `before` middleware, which represent things such as
|
||||
// favicon, static files, application routing.
|
||||
//
|
||||
(function dispatch(i) {
|
||||
if (self.target.modified) {
|
||||
return;
|
||||
}
|
||||
else if (++i === self.before.length) {
|
||||
//
|
||||
// 3. If no match is found then pipe to the 404Stream
|
||||
//
|
||||
return notFound();
|
||||
}
|
||||
|
||||
self.target.once('next', dispatch.bind(null, i));
|
||||
if (self.before[i].length === 3) {
|
||||
self.before[i](self, self.target, function (err) {
|
||||
if (err) {
|
||||
self.onError(err);
|
||||
} else {
|
||||
self.target.emit('next');
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.before[i](self, self.target);
|
||||
}
|
||||
})(-1);
|
||||
};
|
||||
|
||||
RoutingStream.prototype.onError = function (err) {
|
||||
this.emit('error', err);
|
||||
};
|
Reference in New Issue
Block a user