Skip to content

Commit

Permalink
storage: createReadStream: accept start/end offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Dec 9, 2014
1 parent dc4bf20 commit 987ee70
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 10 deletions.
38 changes: 36 additions & 2 deletions lib/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ File.prototype.copy = function(destination, callback) {
* piped to a writable stream or listened to for 'data' events to read a file's
* contents.
*
* @param {object=} options - Configuration object.
* @param {number} options.start - A byte offset to begin the file's download
* from. NOTE: Byte ranges are inclusive; that is, `options.start = 0` and
* `options.end = 999` represent the first 1000 bytes in a file or object.
* @param {number} options.end - A byte offset to stop reading the file at.
* NOTE: Byte ranges are inclusive; that is, `options.start = 0` and
* `options.end = 999` represent the first 1000 bytes in a file or object.
*
* @example
* //-
* // <h4>Downloading a File</h4>
Expand All @@ -225,23 +233,47 @@ File.prototype.copy = function(destination, callback) {
* image.createReadStream()
* .pipe(fs.createWriteStream('/Users/stephen/Photos/image.png'))
* .on('error', function(err) {});
*
* //-
* // To limit the downloaded data to only a byte range, pass an options object.
* //-
* image.createReadStream({
* start: 1050,
* end: 1100
* })
* .pipe(fs.createWriteStream('/Users/stephen/Photos/image.png'))
* .on('error', function(err) {});
*/
File.prototype.createReadStream = function() {
File.prototype.createReadStream = function(options) {
options = options || {};

var storage = this.bucket.storage;
var dup = duplexify();

function createAuthorizedReq(uri) {
var reqOpts = { uri: uri };
var reqOpts = {
uri: uri
};

if (util.is(options.start, 'number') || util.is(options.end, 'number')) {
reqOpts.headers = {
Range: 'bytes=' + [options.start || '', options.end || ''].join('-')
};
}

storage.makeAuthorizedRequest_(reqOpts, {
onAuthorized: function(err, authorizedReqOpts) {
if (err) {
dup.emit('error', err);
dup.end();
return;
}

dup.setReadable(request(authorizedReqOpts));
}
});
}

if (this.metadata.mediaLink) {
createAuthorizedReq(this.metadata.mediaLink);
} else {
Expand All @@ -251,9 +283,11 @@ File.prototype.createReadStream = function() {
dup.end();
return;
}

createAuthorizedReq(metadata.mediaLink);
});
}

return dup;
};

Expand Down
57 changes: 49 additions & 8 deletions test/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ nodeutil.inherits(FakeDuplexify, duplexify);
var makeWritableStream_Override;
var fakeUtil = extend({}, util, {
makeWritableStream: function() {
var args = [].slice.call(arguments);
var args = util.toArray(arguments);
(makeWritableStream_Override || util.makeWritableStream).apply(null, args);
makeWritableStream_Override = null;
}
Expand All @@ -60,7 +60,7 @@ var request_Cached = request;
var request_Override;

function fakeRequest() {
var args = [].slice.apply(arguments);
var args = util.toArray(arguments);
var results = (request_Override || request_Cached).apply(null, args);
request_Override = null;
return results;
Expand Down Expand Up @@ -93,21 +93,24 @@ var File = require('sandboxed-module')

describe('File', function() {
var FILE_NAME = 'file-name.png';
var options = {
makeAuthorizedRequest_: function(req, callback) {
(callback.onAuthorized || callback)(null, req);
}
};
var bucket = new Bucket(options, 'bucket-name');
var file;
var directoryFile;
var bucket;

beforeEach(function() {
var options = {
makeAuthorizedRequest_: function(req, callback) {
(callback.onAuthorized || callback)(null, req);
}
};
bucket = new Bucket(options, 'bucket-name');
file = new File(bucket, FILE_NAME);
file.makeReq_ = util.noop;

directoryFile = new File(bucket, 'directory/file.jpg');
directoryFile.makeReq_ = util.noop;

request_Override = null;
});

describe('initialization', function() {
Expand Down Expand Up @@ -320,6 +323,44 @@ describe('File', function() {
assert.deepEqual(readableStream, dup);
readableStream = null;
});

it('should accept a start range', function(done) {
var startOffset = 100;

request_Override = function(opts) {
assert.equal(opts.headers.Range, 'bytes=' + startOffset + '-');
done();
};

file.metadata = metadata;
file.createReadStream({ start: startOffset });
});

it('should accept an end range', function(done) {
var endOffset = 100;

request_Override = function(opts) {
assert.equal(opts.headers.Range, 'bytes=-' + endOffset);
done();
};

file.metadata = metadata;
file.createReadStream({ end: endOffset });
});

it('should accept both a start and end range', function(done) {
var startOffset = 100;
var endOffset = 101;

request_Override = function(opts) {
var expectedRange = 'bytes=' + startOffset + '-' + endOffset;
assert.equal(opts.headers.Range, expectedRange);
done();
};

file.metadata = metadata;
file.createReadStream({ start: startOffset, end: endOffset });
});
});

describe('createWriteStream', function() {
Expand Down

0 comments on commit 987ee70

Please sign in to comment.