You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							112 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
	
	
							112 lines
						
					
					
						
							2.6 KiB
						
					
					
				'use strict' | 
						|
 | 
						|
var uuid = require('uuid/v4') | 
						|
var CombinedStream = require('combined-stream') | 
						|
var isstream = require('isstream') | 
						|
var Buffer = require('safe-buffer').Buffer | 
						|
 | 
						|
function Multipart (request) { | 
						|
  this.request = request | 
						|
  this.boundary = uuid() | 
						|
  this.chunked = false | 
						|
  this.body = null | 
						|
} | 
						|
 | 
						|
Multipart.prototype.isChunked = function (options) { | 
						|
  var self = this | 
						|
  var chunked = false | 
						|
  var parts = options.data || options | 
						|
 | 
						|
  if (!parts.forEach) { | 
						|
    self.request.emit('error', new Error('Argument error, options.multipart.')) | 
						|
  } | 
						|
 | 
						|
  if (options.chunked !== undefined) { | 
						|
    chunked = options.chunked | 
						|
  } | 
						|
 | 
						|
  if (self.request.getHeader('transfer-encoding') === 'chunked') { | 
						|
    chunked = true | 
						|
  } | 
						|
 | 
						|
  if (!chunked) { | 
						|
    parts.forEach(function (part) { | 
						|
      if (typeof part.body === 'undefined') { | 
						|
        self.request.emit('error', new Error('Body attribute missing in multipart.')) | 
						|
      } | 
						|
      if (isstream(part.body)) { | 
						|
        chunked = true | 
						|
      } | 
						|
    }) | 
						|
  } | 
						|
 | 
						|
  return chunked | 
						|
} | 
						|
 | 
						|
Multipart.prototype.setHeaders = function (chunked) { | 
						|
  var self = this | 
						|
 | 
						|
  if (chunked && !self.request.hasHeader('transfer-encoding')) { | 
						|
    self.request.setHeader('transfer-encoding', 'chunked') | 
						|
  } | 
						|
 | 
						|
  var header = self.request.getHeader('content-type') | 
						|
 | 
						|
  if (!header || header.indexOf('multipart') === -1) { | 
						|
    self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) | 
						|
  } else { | 
						|
    if (header.indexOf('boundary') !== -1) { | 
						|
      self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') | 
						|
    } else { | 
						|
      self.request.setHeader('content-type', header + '; boundary=' + self.boundary) | 
						|
    } | 
						|
  } | 
						|
} | 
						|
 | 
						|
Multipart.prototype.build = function (parts, chunked) { | 
						|
  var self = this | 
						|
  var body = chunked ? new CombinedStream() : [] | 
						|
 | 
						|
  function add (part) { | 
						|
    if (typeof part === 'number') { | 
						|
      part = part.toString() | 
						|
    } | 
						|
    return chunked ? body.append(part) : body.push(Buffer.from(part)) | 
						|
  } | 
						|
 | 
						|
  if (self.request.preambleCRLF) { | 
						|
    add('\r\n') | 
						|
  } | 
						|
 | 
						|
  parts.forEach(function (part) { | 
						|
    var preamble = '--' + self.boundary + '\r\n' | 
						|
    Object.keys(part).forEach(function (key) { | 
						|
      if (key === 'body') { return } | 
						|
      preamble += key + ': ' + part[key] + '\r\n' | 
						|
    }) | 
						|
    preamble += '\r\n' | 
						|
    add(preamble) | 
						|
    add(part.body) | 
						|
    add('\r\n') | 
						|
  }) | 
						|
  add('--' + self.boundary + '--') | 
						|
 | 
						|
  if (self.request.postambleCRLF) { | 
						|
    add('\r\n') | 
						|
  } | 
						|
 | 
						|
  return body | 
						|
} | 
						|
 | 
						|
Multipart.prototype.onRequest = function (options) { | 
						|
  var self = this | 
						|
 | 
						|
  var chunked = self.isChunked(options) | 
						|
  var parts = options.data || options | 
						|
 | 
						|
  self.setHeaders(chunked) | 
						|
  self.chunked = chunked | 
						|
  self.body = self.build(parts, chunked) | 
						|
} | 
						|
 | 
						|
exports.Multipart = Multipart
 | 
						|
 |