diff --git a/Readme.md b/Readme.md index 7e97327..eee134d 100644 --- a/Readme.md +++ b/Readme.md @@ -16,19 +16,27 @@ ## API -### Upload(file) +### Upload(file, options) Initialize an `Upload` with the given `file`, where `file` is a `File` object, for example from a `input.files[0]` `FileList`. ```js -var upload = new Upload(file); +var upload = new Upload(file, options); var upload = Upload(file); ``` +#### Options + + By default the file is uploaded as multipart/form-data. + To upload it directly in the request body set `type` to `body`. + + - `type` `form-data` or `body` + - `method` The used http method + ### Upload#to(path, [fn]) - __POST__ the multipart upload to `path` and invoke `fn(err, res)`. + Upload to `path` and invoke `fn(err, res)`. ```js upload.to('/upload'); diff --git a/index.js b/index.js index db5ddbd..8f0c690 100644 --- a/index.js +++ b/index.js @@ -26,11 +26,14 @@ module.exports = Upload; * @api private */ -function Upload(file) { - if (!(this instanceof Upload)) return new Upload(file); +function Upload(file, options) { + if (!(this instanceof Upload)) return new Upload(file, options); Emitter.call(this); this.file = file; file.slice = file.slice || file.webkitSlice; + options = options || {}; + this.type = options.type || 'form-data'; + this.method = options.method || 'POST'; } /** @@ -49,10 +52,9 @@ Emitter(Upload.prototype); Upload.prototype.to = function(path, fn){ // TODO: x-browser - var self = this; fn = fn || function(){}; var req = this.req = new XMLHttpRequest; - req.open('POST', path); + req.open(this.method, path); req.onload = this.onload.bind(this); req.onerror = this.onerror.bind(this); req.upload.onprogress = this.onprogress.bind(this); @@ -65,9 +67,13 @@ Upload.prototype.to = function(path, fn){ fn(err); } }; - var body = new FormData; - body.append('file', this.file); - req.send(body); + if ('body' == this.type) { + req.send(this.file); + } else { + var body = new FormData; + body.append('file', this.file); + req.send(body); + } }; /** diff --git a/test/server.js b/test/server.js index 20b4cdf..ecd08c7 100644 --- a/test/server.js +++ b/test/server.js @@ -20,6 +20,13 @@ app.post('/upload', function(req, res){ res.send(400); }); +app.put('/upload/body', function(req, res){ + res.status(200); + res.setHeader('Content-Type', req.headers['content-type']); + res.setHeader('Content-Length', req.headers['content-length']); + req.pipe(res); +}); + app.post('/failure', function(req, res){ res.send(500, 'something blew up'); }); diff --git a/test/tests.html b/test/tests.html index bead4c8..5c5433e 100644 --- a/test/tests.html +++ b/test/tests.html @@ -5,7 +5,6 @@
- diff --git a/test/tests.js b/test/tests.js index 30311bb..44c7304 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,7 +1,7 @@ var Upload = require('upload'); -var input = document.getElementById('file'); +var file = new Blob(['blob'], {type: 'text/blob'}); function assert(expr, msg) { if (!expr) throw new Error(msg || 'assertion failed'); @@ -9,7 +9,7 @@ function assert(expr, msg) { describe('Upload', function(){ it('should be an emitter', function(done){ - var upload = new Upload; + var upload = new Upload('something'); upload.on('something', done); upload.emit('something'); }) @@ -20,63 +20,62 @@ describe('Upload', function(){ describe('#to(path)', function(){ it('should POST to the given path', function(done){ - this.timeout(0); - input.addEventListener('change', function(){ - var file = input.files[0]; - var upload = new Upload(file); - assert(file == upload.file, '.file'); - upload.to('/upload'); - upload.on('end', function(res){ - assert(200 == res.status, '200 response'); - done(); - }); - }, false); + var upload = new Upload(file); + assert(file == upload.file, '.file'); + upload.to('/upload'); + upload.on('end', function(res){ + assert(200 == res.status, '200 response'); + done(); + }); }) it('should emit "progress" events', function(done){ - this.timeout(0); - input.addEventListener('change', function(){ - var file = input.files[0]; - var upload = new Upload(file); - upload.to('/upload'); + var upload = new Upload(file); + upload.to('/upload'); - upload.on('progress', function(e){ - assert('progress' == e.type); - assert(e.percent, 'e.percent'); - }); + upload.on('progress', function(e){ + assert('progress' == e.type); + assert(e.percent, 'e.percent'); + }); - upload.on('end', function(res){ - done(); - }); - }, false); + upload.on('end', function(res){ + done(); + }); }) }) describe('#to(path, [fn])', function(){ it('should pass errors', function(done){ - this.timeout(0); - input.addEventListener('change', function(){ - var file = input.files[0]; - var upload = new Upload(file); - upload.to('/failure', function(err){ - assert('Internal Server Error: something blew up' == err.message); - assert(500 == err.status); - done(); - }); - }, false); + var upload = new Upload(file); + upload.to('/failure', function(err){ + assert('Internal Server Error: something blew up' == err.message); + assert(500 == err.status); + done(); + }); + }) + + it('should upload in request body', function(done){ + var upload = new Upload(file, { + type: 'body' + , method: 'put' + }); + upload.to('/upload/body', function(err, res){ + var resLength = parseInt(res.getResponseHeader('content-length'), 10) + , resType = res.getResponseHeader('content-type'); + assert(file.size == resLength); + assert(file.type == resType); + assert(!err); + done(); + }); }) it('should pass responses', function(done){ - this.timeout(0); - input.addEventListener('change', function(){ - var file = input.files[0]; - var upload = new Upload(file); - upload.to('/upload', function(err, res){ - assert(!err); - assert(200 == res.status); - done(); - }); - }, false); + var upload = new Upload(file); + upload.to('/upload', function(err, res){ + assert(!err); + assert(200 == res.status); + done(); + }); }) }) })