/** * <p>Creates instance of MailParser which in turn extends Stream</p> * * <p>Options object has the following properties:</p> * * <ul> * <li><b>debug</b> - if set to true print all incoming lines to decodeq</li> * <li><b>streamAttachments</b> - if set to true, stream attachments instead of including them</li> * <li><b>unescapeSMTP</b> - if set to true replace double dots in the beginning of the file</li> * <li><b>defaultCharset</b> - the default charset for text/plain, text/html content, if not set reverts to Latin-1 * <li><b>showAttachmentLinks</b></li> - if set to true, show inlined attachment links * </ul> * * @constructor * @param {Object} [options] Optional options object */ function MailParser(options) { // Make MailParser a Stream object Stream.call(this); this.writable = true; /** * Options object * @public */ this.options = options || {}; /** * Indicates current state the parser is in * @private */ this._state = STATES.header; /** * The remaining data from the previos chunk which is waiting to be processed * @private */ this._remainder = ""; /** * The complete tree structure of the e-mail * @public */ this.mimeTree = this._createMimeNode(); /** * Current node of the multipart mime tree that is being processed * @private */ this._currentNode = this.mimeTree; // default values for the root node this._currentNode.priority = "normal"; /** * An object of already used attachment filenames * @private */ this._fileNames = {}; /** * An array of multipart nodes * @private */ this._multipartTree = []; /** * This is the final mail structure object that is returned to the client * @public */ this.mailData = {}; /** * Line counter for debugging * @private */ this._lineCounter = 0; /** * Did the last chunk end with \r * @private */ this._lineFeed = false; /** * Is the "headers" event already emitted * @private */ this._headersSent = false; /** * If the e-mail is in mbox format, unescape ">From " to "From " in body * @private */ this._isMbox = -1; }
client.on('disconnect', function () { stream.writable = false; stream.readable = false; stream.emit('end'); });
stream.on('error', function (err) { err.transport = err.transport || []; err.transport.push(transport.name); out.emit('error', err); });
function SlowStream(trickle) { stream.Stream.call(this); this.trickle = trickle; this.offset = 0; this.readable = this.writable = true; }
function FrameGenerator() { Stream.call(this); this.readable = true; }
function Readable() { this.readable = true; stream.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) { process.nextTick(function() { self._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(); }); };
unzip.on('end', function(){ decodedStream.emit('end'); });
var ReadableStreamBuffer = module.exports = function(opts) { var that = this; stream.Stream.call(this); opts = opts || {}; var frequency = opts.hasOwnProperty("frequency") ? opts.frequency : constants.DEFAULT_FREQUENCY; var chunkSize = opts.chunkSize || constants.DEFAULT_CHUNK_SIZE; var initialSize = opts.initialSize || constants.DEFAULT_INITIAL_SIZE; var incrementAmount = opts.incrementAmount || constants.DEFAULT_INCREMENT_AMOUNT; var size = 0; var buffer = new Buffer(initialSize); var encoding = null; this.readable = true; this.writable = false; var sendData = function() { var amount = Math.min(chunkSize, size); if (amount > 0) { var chunk = null; if(encoding) { chunk = buffer.toString(encoding, 0, amount); } else { chunk = new Buffer(amount); buffer.copy(chunk, 0, 0, amount); } that.emit("data", chunk); if(amount < buffer.length) buffer.copy(buffer, 0, amount, size); size -= amount; } if(size === 0 && !that.readable) { that.emit("end"); that.emit("close"); if (sendData && sendData.interval) { clearInterval(sendData.interval); sendData.interval = null; } } }; this.size = function() { return size; }; this.maxSize = function() { return buffer.length; }; var increaseBufferIfNecessary = function(incomingDataSize) { if((buffer.length - size) < incomingDataSize) { var factor = Math.ceil((incomingDataSize - (buffer.length - size)) / incrementAmount); var newBuffer = new Buffer(buffer.length + (incrementAmount * factor)); buffer.copy(newBuffer, 0, 0, size); buffer = newBuffer; } }; this.put = function(data, encoding) { if(!that.readable) return; var wasEmpty = size === 0; if(Buffer.isBuffer(data)) { increaseBufferIfNecessary(data.length); data.copy(buffer, size, 0); size += data.length; } else { data = data + ""; var dataSizeInBytes = Buffer.byteLength(data); increaseBufferIfNecessary(dataSizeInBytes); buffer.write(data, size, encoding || "utf8"); size += dataSizeInBytes; } if (wasEmpty && size > 0) { this.emit('readable') } if (!this.isPaused && !frequency) { while (size > 0) { sendData(); } } }; this.pause = function() { this.isPaused = true; if(sendData && sendData.interval) { clearInterval(sendData.interval); delete sendData.interval; } }; this.resume = function() { this.isPaused = false; if(sendData && !sendData.interval && frequency > 0) { sendData.interval = setInterval(sendData, frequency); } }; this.destroy = function() { that.emit("end"); if(sendData.interval) clearInterval(sendData.interval); sendData = null; that.readable = false; that.emit("close"); }; this.destroySoon = function() { that.readable = false; if (!sendData.interval) { that.emit("end"); that.emit("close"); } }; this.setEncoding = function(_encoding) { encoding = _encoding; }; this.resume(); };
this.on('end', function () { stream.emit('end'); });
unzip.on('data', function(buf){ var str = decoder.write(buf); if (str.length) decodedStream.emit('data', str); });
this.on('part', function (part) { stream.emit('data', part); });
s.listen(s.port, function () { counter = 0; var check = function () { counter = counter - 1 if (counter === 0) { console.log('All tests passed.') setTimeout(function () { process.exit(); }, 500) } } // Test pipeing to a request object s.once('/push', server.createPostValidator("mydata")); var mydata = new stream.Stream(); mydata.readable = true counter++ var r1 = request.put({url: 'http://localhost:3453/push'}, function () { check(); }) mydata.pipe(r1) mydata.emit('data', 'mydata'); mydata.emit('end'); // Test pipeing to a request object with a json body s.once('/push-json', server.createPostValidator("{\"foo\":\"bar\"}", "application/json")); var mybodydata = new stream.Stream(); mybodydata.readable = true counter++ var r2 = request.put({url: 'http://localhost:3453/push-json', json: true}, function () { check(); }) mybodydata.pipe(r2) mybodydata.emit('data', JSON.stringify({foo: "bar"})); mybodydata.emit('end'); // Test pipeing from a request object. s.once('/pull', server.createGetResponse("mypulldata")); var mypulldata = new stream.Stream(); mypulldata.writable = true counter++ request({url: 'http://localhost:3453/pull'}).pipe(mypulldata) var d = ''; mypulldata.write = function (chunk) { d += chunk; } mypulldata.end = function () { assert.equal(d, 'mypulldata'); check(); }; s.on('/cat', function (req, resp) { if (req.method === "GET") { resp.writeHead(200, {'content-type': 'text/plain-test', 'content-length': 4}); resp.end('asdf') } else if (req.method === "PUT") { assert.equal(req.headers['content-type'], 'text/plain-test'); assert.equal(req.headers['content-length'], 4) var validate = ''; req.on('data', function (chunk) { validate += chunk }) req.on('end', function () { resp.writeHead(201); resp.end(); assert.equal(validate, 'asdf'); check(); }) } }) s.on('/pushjs', function (req, resp) { if (req.method === "PUT") { assert.equal(req.headers['content-type'], 'application/javascript'); check(); } }) s.on('/catresp', function (req, resp) { request.get('http://localhost:3453/cat').pipe(resp) }) s.on('/doodle', function (req, resp) { if (req.headers['x-oneline-proxy']) { resp.setHeader('x-oneline-proxy', 'yup') } resp.writeHead('200', {'content-type': 'image/jpeg'}) fs.createReadStream(path.join(__dirname, 'googledoodle.jpg')).pipe(resp) }) s.on('/onelineproxy', function (req, resp) { var x = request('http://localhost:3453/doodle') req.pipe(x) x.pipe(resp) }) counter++ fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) counter++ request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) counter++ request.get('http://localhost:3453/catresp', function (e, resp, body) { assert.equal(resp.headers['content-type'], 'text/plain-test'); assert.equal(resp.headers['content-length'], 4) check(); }) var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.jpg')) counter++ request.get('http://localhost:3453/doodle').pipe(doodleWrite) doodleWrite.on('close', function () { assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')), fs.readFileSync(path.join(__dirname, 'test.jpg'))) check() }) process.on('exit', function () { fs.unlinkSync(path.join(__dirname, 'test.jpg')) }) counter++ request.get({uri: 'http://localhost:3453/onelineproxy', headers: {'x-oneline-proxy': 'nope'}}, function (err, resp, body) { assert.equal(resp.headers['x-oneline-proxy'], 'yup') check() }) s.on('/afterresponse', function (req, resp) { resp.write('d') resp.end() }) counter++ var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { var v = new ValidationStream('d') afterresp.pipe(v) v.on('end', check) }) s.on('/forward1', function (req, resp) { resp.writeHead(302, {location: '/forward2'}) resp.end() }) s.on('/forward2', function (req, resp) { resp.writeHead('200', {'content-type': 'image/png'}) resp.write('d') resp.end() }) counter++ var validateForward = new ValidationStream('d') validateForward.on('end', check) request.get('http://localhost:3453/forward1').pipe(validateForward) // Test pipe options s.once('/opts', server.createGetResponse('opts response')); var optsStream = new stream.Stream(); optsStream.writable = true var optsData = ''; optsStream.write = function (buf) { optsData += buf; if (optsData === 'opts response') { setTimeout(check, 10); } } optsStream.end = function () { assert.fail('end called') }; counter++ request({url: 'http://localhost:3453/opts'}).pipe(optsStream, { end: false }) })
ColumnFamily.prototype.getRange = function (options) { options = options || {}; var self = this, consistency = options.consistency || options.consistencyLevel || DEFAULT_READ_CONSISTENCY, predicate = getSlicePredicate(options, this.columnMarshaller), iterations = 0, stream = new Stream(), keyRange, keyRangeOptions = {}; if (typeof options.start !== 'undefined') keyRangeOptions.start_key = options.start; if (typeof options.end !== 'undefined') keyRangeOptions.end_key = options.end; if (typeof options.count !== 'undefined') { keyRangeOptions.count = options.count; } keyRange = new ttype.KeyRange(keyRangeOptions); function iterator () { self.connection.execute('get_range_slices', columnParent(self), predicate, keyRange, consistency, onComplete); } function onComplete(err, val){ if(err){ stream.emit('error', err); return; } var i = 0, len = val.length, row, count = 0; for(; i < len; i += 1){ // First key is a duplicate from the last iteration. if (iterations > 0 && i === 0) continue; row = val[i]; stream.emit('data', Row.fromThrift(self.keyMarshaller.deserialize(row.key), row.columns, self)); // Track how many items we have emitted count += 1; } iterations += 1; if (count > 0){ var startKey = val[len - 1].key; delete keyRangeOptions.start_token; keyRangeOptions.start_key = startKey; keyRange = new ttype.KeyRange(keyRangeOptions); process.nextTick(iterator); } else { stream.emit('end'); } } // Start our stream next tick process.nextTick(iterator); return stream; };
stream.destroy = function () { stream.emit('end') stream.emit('close') ended = true }
stream.write = function (data) { parser.write(data.toString()) stream.emit(data) }
function Writable() { this.writable = true; stream.Stream.call(this); }
parser.onend = function () { stream.end() };
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) { 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.dataCallback = options.dataCallback || function (data) { options.parser(self, data); }; options.disconnectedCallback = options.disconnectedCallback || function () { if (self.closing) { return; } var err = new Error("Disconnected"); callback(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; if (options.encoding) { this.setEncoding(this.encoding); } } this.options = options; this.path = path; if (openImmediately) { process.nextTick(function () { self.open(callback); }); } }
parser.onend = function () { stream.end() if (val) val() }
req.on('error', function (err) { stream.emit('error', err); });
str.on('log', log => { log.transport = log.transport || []; log.transport.push(transport.name); out.emit('log', log); });
/* * Exported bindings */ /** * Construct a Sink instance, which collects data events coming from the * indicated source stream. Sink instances are in turn instances of * `stream.Stream`. */ function Sink(source, options) { options = opts.validate(options, OPTIONS); stream.Stream.call(this); this.sink = sealer.seal(new State(this, source)); opts.handleCommon(options, this); }
str.on('error', err => { err.transport = err.transport || []; err.transport.push(transport.name); out.emit('error', err); });
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 }) }
function StripThings() { this.readable = this.writable = true; Stream.call(this); }
stream.on('log', function (log) { log.transport = log.transport || []; log.transport.push(transport.name); out.emit('log', log); });
stream.destroy = function () { ended = true stream.emit('close') }
function BufferStream () { Stream.apply(this); this.finished = false; this.writable = true; }
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 || mimetypes.lookup(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 = mimetypes.lookup(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) } } }) }