150 lines
3.0 KiB
JavaScript
150 lines
3.0 KiB
JavaScript
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var util = require('util');
|
||
|
var mime = require('mime');
|
||
|
var FormData = require('form-data');
|
||
|
var PassThrough = require('readable-stream/passthrough');
|
||
|
|
||
|
/**
|
||
|
* Initialize a new `Part` for the given `req`.
|
||
|
*
|
||
|
* @param {Request} req
|
||
|
* @api public
|
||
|
* @deprecated pass a readable stream in to `Request#attach()` instead
|
||
|
*/
|
||
|
|
||
|
var Part = function (req) {
|
||
|
PassThrough.call(this);
|
||
|
this._req = req;
|
||
|
this._attached = false;
|
||
|
this._name = null;
|
||
|
this._type = null;
|
||
|
this._header = null;
|
||
|
this._filename = null;
|
||
|
|
||
|
this.once('pipe', this._attach.bind(this));
|
||
|
};
|
||
|
Part = util.deprecate(Part, 'The `Part()` constructor is deprecated. ' +
|
||
|
'Pass a readable stream in to `Request#attach()` instead.');
|
||
|
|
||
|
/**
|
||
|
* Inherit from `PassThrough`.
|
||
|
*/
|
||
|
|
||
|
util.inherits(Part, PassThrough);
|
||
|
|
||
|
/**
|
||
|
* Expose `Part`.
|
||
|
*/
|
||
|
|
||
|
module.exports = Part;
|
||
|
|
||
|
/**
|
||
|
* Set header `field` to `val`.
|
||
|
*
|
||
|
* @param {String} field
|
||
|
* @param {String} val
|
||
|
* @return {Part} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Part.prototype.set = function(field, val){
|
||
|
//if (!this._header) this._header = {};
|
||
|
//this._header[field] = val;
|
||
|
//return this;
|
||
|
throw new TypeError('setting custom form-data part headers is unsupported');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set _Content-Type_ response header passed through `mime.lookup()`.
|
||
|
*
|
||
|
* Examples:
|
||
|
*
|
||
|
* res.type('html');
|
||
|
* res.type('.html');
|
||
|
*
|
||
|
* @param {String} type
|
||
|
* @return {Part} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Part.prototype.type = function(type){
|
||
|
var lookup = mime.lookup(type);
|
||
|
this._type = lookup;
|
||
|
//this.set('Content-Type', lookup);
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set the "name" portion for the _Content-Disposition_ header field.
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @return {Part} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Part.prototype.name = function(name){
|
||
|
this._name = name;
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set _Content-Disposition_ header field to _attachment_ with `filename`
|
||
|
* and field `name`.
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @param {String} filename
|
||
|
* @return {Part} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Part.prototype.attachment = function(name, filename){
|
||
|
this.name(name);
|
||
|
if (filename) {
|
||
|
this.type(filename);
|
||
|
this._filename = filename;
|
||
|
}
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Calls `FormData#append()` on the Request instance's FormData object.
|
||
|
*
|
||
|
* Gets called implicitly upon the first `write()` call, or the "pipe" event.
|
||
|
*
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
Part.prototype._attach = function(){
|
||
|
if (this._attached) return;
|
||
|
this._attached = true;
|
||
|
|
||
|
if (!this._name) throw new Error('must call `Part#name()` first!');
|
||
|
|
||
|
// add `this` Stream's readable side as a stream for this Part
|
||
|
this._req._getFormData().append(this._name, this, {
|
||
|
contentType: this._type,
|
||
|
filename: this._filename
|
||
|
});
|
||
|
|
||
|
// restore PassThrough's default `write()` function now that we're setup
|
||
|
this.write = PassThrough.prototype.write;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Write `data` with `encoding`.
|
||
|
*
|
||
|
* @param {Buffer|String} data
|
||
|
* @param {String} encoding
|
||
|
* @return {Boolean}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Part.prototype.write = function(){
|
||
|
this._attach();
|
||
|
return this.write.apply(this, arguments);
|
||
|
};
|