forked from andrewrk/node-s3-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 04fc22a
Showing
5 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
var knox = require('knox') | ||
, EventEmitter = require('events').EventEmitter | ||
, fs = require('fs'); | ||
|
||
exports.createClient = function(options) { | ||
return new Client(options); | ||
}; | ||
|
||
function Client(options) { | ||
this.knox = knox.createClient(options); | ||
} | ||
|
||
Client.prototype.upload = function(localFile, remoteFile) { | ||
var uploader = new EventEmitter(); | ||
var knoxUpload = this.knox.putFile(localFile, remoteFile, function (err, resp) { | ||
if (err) { | ||
uploader.emit('error', err); | ||
} else if (resp.statusCode === 200) { | ||
uploader.emit('end'); | ||
} else { | ||
uploader.emit('error', new Error("s3 http status code " + resp.statusCode)); | ||
} | ||
}); | ||
knoxUpload.on('progress', function (progress) { | ||
uploader.emit('progress', progress.written, progress.total); | ||
}); | ||
return uploader; | ||
}; | ||
|
||
Client.prototype.download = function(remoteFile, localFile) { | ||
var downloader = new EventEmitter(); | ||
var amountDone = 0; | ||
var amountTotal; | ||
var writeStream; | ||
var knoxDownload = this.knox.getFile(remoteFile, function (err, resp) { | ||
if (err) { | ||
downloader.emit('error', err); | ||
} else if (resp.statusCode === 200) { | ||
amountTotal = parseInt(resp.headers['content-length'], 10); | ||
var writeStream = fs.createWriteStream(localFile); | ||
writeStream.on('error', onError); | ||
resp.on('error', onError); | ||
resp.on('end', onSuccess); | ||
resp.on('data', onData); | ||
resp.pipe(writeStream); | ||
} else { | ||
downloader.emit('error', new Error("s3 http status code" + resp.statusCode)); | ||
} | ||
function removeListeners() { | ||
writeStream.removeListener('error', onError); | ||
resp.removeListener('error', onError); | ||
resp.removeListener('end', onSuccess); | ||
} | ||
function onError(err) { | ||
removeListeners(); | ||
writeStream.destroy(); | ||
downloader.emit('error', err); | ||
} | ||
function onSuccess() { | ||
removeListeners(); | ||
writeStream.end(); | ||
downloader.emit('end'); | ||
} | ||
function onData(data) { | ||
amountDone += data.length; | ||
downloader.emit('progress', amountDone, amountTotal); | ||
} | ||
}); | ||
return downloader; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "s3", | ||
"version": "0.0.0", | ||
"description": "high level amazon s3 client using knox as a backend", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/superjoe30/node-s3" | ||
}, | ||
"keywords": [ | ||
"amazon", | ||
"s3", | ||
"high", | ||
"level", | ||
"api" | ||
], | ||
"author": "Andrew Kelley", | ||
"license": "BSD", | ||
"devDependencies": { | ||
"mocha": "~1.7.1", | ||
"mkdirp": "~0.3.4" | ||
}, | ||
"dependencies": { | ||
"knox": "~0.4.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
Usage: | ||
------ | ||
```js | ||
// configure | ||
var s3 = require('s3'); | ||
var client = s3.createClient({ | ||
key: "your s3 key", | ||
secret: "your s3 secret", | ||
bucket: "your s3 bucket" | ||
}); | ||
// createClient allows any options that knox does. | ||
|
||
// upload a file to s3 | ||
var uploader = client.upload("some/local/file", "some/remote/file"); | ||
uploader.on('error', function(err) { | ||
console.error("unable to upload:", err.stack); | ||
}); | ||
uploader.on('progress', function(amountDone, amountTotal) { | ||
console.log("progress", amountDone, amountTotal); | ||
}); | ||
uploader.on('end', function() { | ||
console.log("done"); | ||
}); | ||
|
||
// download a file from s3 | ||
var downloader = client.download("some/remote/file", "some/local/file"); | ||
downloader.on('error', function(err) { | ||
console.error("unable to upload:", err.stack); | ||
}); | ||
downloader.on('progress', function(amountDone, amountTotal) { | ||
console.log("progress", amountDone, amountTotal); | ||
}); | ||
downloader.on('end', function() { | ||
console.log("done"); | ||
}); | ||
``` | ||
|
||
This module uses [knox](https://github.com/LearnBoost/knox) as a backend. If | ||
you want to do more low-level things, use knox for those things. It's ok to use | ||
both. | ||
|
||
Testing: | ||
-------- | ||
S3_KEY=<valid_s3_key> S3_SECRET=<valid_s3_secret> S3_BUCKET=<valid_s3_bucket> npm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
var s3 = require('../') | ||
, path = require('path') | ||
, assert = require('assert') | ||
, fs = require('fs') | ||
, mkdirp = require('mkdirp') | ||
, crypto = require('crypto') | ||
, tempDir = path.join(__dirname, 'tmp') | ||
, localFile = path.join(tempDir, 'random') | ||
, remoteFile = "/node-s3-test/file.png" | ||
|
||
function createClient() { | ||
return s3.createClient({ | ||
key: process.env.S3_KEY, | ||
secret: process.env.S3_SECRET, | ||
bucket: process.env.S3_BUCKET | ||
}); | ||
} | ||
|
||
function createBigFile(cb) { | ||
mkdirp(tempDir, function(err) { | ||
if (err) return cb(err); | ||
var md5sum = crypto.createHash('md5'); | ||
var out = fs.createWriteStream(localFile); | ||
out.on('error', function(err) { | ||
cb(err); | ||
}); | ||
out.on('close', function() { | ||
cb(null, md5sum.digest('hex')); | ||
}); | ||
var str = "abcdefghijklmnopqrstuvwxyz"; | ||
for (var i = 0; i < 4000; ++i) { | ||
out.write(str); | ||
md5sum.update(str); | ||
} | ||
out.end(); | ||
}); | ||
} | ||
|
||
describe("s3", function () { | ||
var hexdigest; | ||
it("uploads", function(done) { | ||
createBigFile(function (err, _hexdigest) { | ||
if (err) return done(err); | ||
hexdigest = _hexdigest; | ||
var client = createClient(); | ||
var uploader = client.upload(localFile, remoteFile); | ||
uploader.on('error', done); | ||
var progress = 0; | ||
var progressEventCount = 0; | ||
uploader.on('progress', function(amountDone, amountTotal) { | ||
var newProgress = amountDone / amountTotal; | ||
progressEventCount += 1; | ||
assert(newProgress >= progress, "old progress: " + progress + ", new progress: " + newProgress); | ||
progress = newProgress; | ||
}); | ||
uploader.on('end', function() { | ||
assert.strictEqual(progress, 1); | ||
assert(progressEventCount >= 3, "expected at least 3 progress events. got " + progressEventCount); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it("dowloads", function(done) { | ||
fs.unlink(localFile, function(err) { | ||
if (err) return done(err); | ||
var client = createClient(); | ||
var downloader = client.download(remoteFile, localFile); | ||
downloader.on('error', done); | ||
var progress = 0; | ||
var progressEventCount = 0; | ||
downloader.on('progress', function(amountDone, amountTotal) { | ||
var newProgress = amountDone / amountTotal; | ||
progressEventCount += 1; | ||
assert(newProgress >= progress, "old progress: " + progress + ", new progress: " + newProgress); | ||
progress = newProgress; | ||
}); | ||
downloader.on('end', function() { | ||
assert.strictEqual(progress, 1); | ||
assert(progressEventCount >= 3, "expected at least 3 progress events. got " + progressEventCount); | ||
var reader = fs.createReadStream(localFile); | ||
var md5sum = crypto.createHash('md5'); | ||
reader.on('data', function(data) { | ||
md5sum.update(data); | ||
}); | ||
reader.on('error', function (err) { | ||
done(err); | ||
}); | ||
reader.on('end', function() { | ||
assert.strictEqual(md5sum.digest('hex'), hexdigest); | ||
fs.unlink(localFile, done); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |