Skip to content

Commit

Permalink
Adds memory file system support (including tests) Closes pillarjs#160
Browse files Browse the repository at this point in the history
* Enables configuration to specify which file system to use to send files by default.
  Default: standard node js fs module (require('fs'))
* Provides basic tests via global injection
  • Loading branch information
hinell committed Feb 13, 2019
1 parent acefad9 commit 28c12bb
Show file tree
Hide file tree
Showing 6 changed files with 2,378 additions and 116 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ Serve files relative to `path`.
Byte offset at which the stream starts, defaults to 0. The start is inclusive,
meaning `start: 2` will include the 3rd byte in the stream.

##### fs

File system to serve files by default. **Default** value is [fs](https://nodejs.org/api/fs.html).

#### Events

The `SendStream` is an event emitter and will emit the following events:
Expand Down
23 changes: 18 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ var encodeUrl = require('encodeurl')
var escapeHtml = require('escape-html')
var etag = require('etag')
var fresh = require('fresh')
var fs = require('fs')
var mime = require('mime')
var ms = require('ms')
var onFinished = require('on-finished')
Expand Down Expand Up @@ -84,6 +83,10 @@ function send (req, path, options) {
return new SendStream(req, path, options)
}

var errors = {}
errors.INVALID_OPTION_FS_STAT = new TypeError('Invalid option: Incompatible file system interface: fs.stat() method is expected')
errors.INVALID_OPTION_FS_CRTSTRM = new TypeError('Invalid option: Incompatible file system interface: fs.createReadStream() method is expected')
send.errors = errors
/**
* Initialize a `SendStream` with the given `path`.
*
Expand All @@ -101,6 +104,16 @@ function SendStream (req, path, options) {
this.options = opts
this.path = path
this.req = req
this.fs = opts.fs || require('fs')

// Checking if provided "fs" is compatible
if (!typeof this.fs.stat === `function`) {
throw errors.INVALID_OPTION_FS_STAT
}

if (!typeof this.fs.createReadStream === `function`) {
throw errors.INVALID_OPTION_FS_CRTSTRM
}

this._acceptRanges = opts.acceptRanges !== undefined
? Boolean(opts.acceptRanges)
Expand Down Expand Up @@ -718,7 +731,7 @@ SendStream.prototype.sendFile = function sendFile (path) {
var self = this

debug('stat "%s"', path)
fs.stat(path, function onstat (err, stat) {
this.fs.stat(path, function onstat (err, stat) {
if (err && err.code === 'ENOENT' && !extname(path) && path[path.length - 1] !== sep) {
// not found, check extensions
return next(err)
Expand All @@ -739,7 +752,7 @@ SendStream.prototype.sendFile = function sendFile (path) {
var p = path + '.' + self._extensions[i++]

debug('stat "%s"', p)
fs.stat(p, function (err, stat) {
self.fs.stat(p, function (err, stat) {
if (err) return next(err)
if (stat.isDirectory()) return next()
self.emit('file', p, stat)
Expand Down Expand Up @@ -767,7 +780,7 @@ SendStream.prototype.sendIndex = function sendIndex (path) {
var p = join(path, self._index[i])

debug('stat "%s"', p)
fs.stat(p, function (err, stat) {
self.fs.stat(p, function (err, stat) {
if (err) return next(err)
if (stat.isDirectory()) return next()
self.emit('file', p, stat)
Expand All @@ -793,7 +806,7 @@ SendStream.prototype.stream = function stream (path, options) {
var res = this.res

// pipe
var stream = fs.createReadStream(path, options)
var stream = this.fs.createReadStream(path, options)
this.emit('stream', stream)
stream.pipe(res)

Expand Down

0 comments on commit 28c12bb

Please sign in to comment.