diff options
| author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 | 
|---|---|---|
| committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 | 
| commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
| tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/form-data/lib | |
| parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
| download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip  | |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/form-data/lib')
| -rw-r--r-- | node_modules/form-data/lib/browser.js | 2 | ||||
| -rw-r--r-- | node_modules/form-data/lib/form_data.js | 498 | ||||
| -rw-r--r-- | node_modules/form-data/lib/populate.js | 10 | 
3 files changed, 510 insertions, 0 deletions
diff --git a/node_modules/form-data/lib/browser.js b/node_modules/form-data/lib/browser.js new file mode 100644 index 0000000..09e7c70 --- /dev/null +++ b/node_modules/form-data/lib/browser.js @@ -0,0 +1,2 @@ +/* eslint-env browser */ +module.exports = typeof self == 'object' ? self.FormData : window.FormData; diff --git a/node_modules/form-data/lib/form_data.js b/node_modules/form-data/lib/form_data.js new file mode 100644 index 0000000..cf836b0 --- /dev/null +++ b/node_modules/form-data/lib/form_data.js @@ -0,0 +1,498 @@ +var CombinedStream = require('combined-stream'); +var util = require('util'); +var path = require('path'); +var http = require('http'); +var https = require('https'); +var parseUrl = require('url').parse; +var fs = require('fs'); +var mime = require('mime-types'); +var asynckit = require('asynckit'); +var populate = require('./populate.js'); + +// Public API +module.exports = FormData; + +// make it a Stream +util.inherits(FormData, CombinedStream); + +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + */ +function FormData(options) { +  if (!(this instanceof FormData)) { +    return new FormData(options); +  } + +  this._overheadLength = 0; +  this._valueLength = 0; +  this._valuesToMeasure = []; + +  CombinedStream.call(this); + +  options = options || {}; +  for (var option in options) { +    this[option] = options[option]; +  } +} + +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + +FormData.prototype.append = function(field, value, options) { + +  options = options || {}; + +  // allow filename as single option +  if (typeof options == 'string') { +    options = {filename: options}; +  } + +  var append = CombinedStream.prototype.append.bind(this); + +  // all that streamy business can't handle numbers +  if (typeof value == 'number') { +    value = '' + value; +  } + +  // https://github.com/felixge/node-form-data/issues/38 +  if (util.isArray(value)) { +    // Please convert your array into string +    // the way web server expects it +    this._error(new Error('Arrays are not supported.')); +    return; +  } + +  var header = this._multiPartHeader(field, value, options); +  var footer = this._multiPartFooter(); + +  append(header); +  append(value); +  append(footer); + +  // pass along options.knownLength +  this._trackLength(header, value, options); +}; + +FormData.prototype._trackLength = function(header, value, options) { +  var valueLength = 0; + +  // used w/ getLengthSync(), when length is known. +  // e.g. for streaming directly from a remote server, +  // w/ a known file a size, and not wanting to wait for +  // incoming file to finish to get its size. +  if (options.knownLength != null) { +    valueLength += +options.knownLength; +  } else if (Buffer.isBuffer(value)) { +    valueLength = value.length; +  } else if (typeof value === 'string') { +    valueLength = Buffer.byteLength(value); +  } + +  this._valueLength += valueLength; + +  // @check why add CRLF? does this account for custom/multiple CRLFs? +  this._overheadLength += +    Buffer.byteLength(header) + +    FormData.LINE_BREAK.length; + +  // empty or either doesn't have path or not an http response +  if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { +    return; +  } + +  // no need to bother with the length +  if (!options.knownLength) { +    this._valuesToMeasure.push(value); +  } +}; + +FormData.prototype._lengthRetriever = function(value, callback) { + +  if (value.hasOwnProperty('fd')) { + +    // take read range into a account +    // `end` = Infinity –> read file till the end +    // +    // TODO: Looks like there is bug in Node fs.createReadStream +    // it doesn't respect `end` options without `start` options +    // Fix it when node fixes it. +    // https://github.com/joyent/node/issues/7819 +    if (value.end != undefined && value.end != Infinity && value.start != undefined) { + +      // when end specified +      // no need to calculate range +      // inclusive, starts with 0 +      callback(null, value.end + 1 - (value.start ? value.start : 0)); + +    // not that fast snoopy +    } else { +      // still need to fetch file size from fs +      fs.stat(value.path, function(err, stat) { + +        var fileSize; + +        if (err) { +          callback(err); +          return; +        } + +        // update final size based on the range options +        fileSize = stat.size - (value.start ? value.start : 0); +        callback(null, fileSize); +      }); +    } + +  // or http response +  } else if (value.hasOwnProperty('httpVersion')) { +    callback(null, +value.headers['content-length']); + +  // or request stream http://github.com/mikeal/request +  } else if (value.hasOwnProperty('httpModule')) { +    // wait till response come back +    value.on('response', function(response) { +      value.pause(); +      callback(null, +response.headers['content-length']); +    }); +    value.resume(); + +  // something else +  } else { +    callback('Unknown stream'); +  } +}; + +FormData.prototype._multiPartHeader = function(field, value, options) { +  // custom header specified (as string)? +  // it becomes responsible for boundary +  // (e.g. to handle extra CRLFs on .NET servers) +  if (typeof options.header == 'string') { +    return options.header; +  } + +  var contentDisposition = this._getContentDisposition(value, options); +  var contentType = this._getContentType(value, options); + +  var contents = ''; +  var headers  = { +    // add custom disposition as third element or keep it two elements if not +    'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), +    // if no content type. allow it to be empty array +    'Content-Type': [].concat(contentType || []) +  }; + +  // allow custom headers. +  if (typeof options.header == 'object') { +    populate(headers, options.header); +  } + +  var header; +  for (var prop in headers) { +    if (!headers.hasOwnProperty(prop)) continue; +    header = headers[prop]; + +    // skip nullish headers. +    if (header == null) { +      continue; +    } + +    // convert all headers to arrays. +    if (!Array.isArray(header)) { +      header = [header]; +    } + +    // add non-empty headers. +    if (header.length) { +      contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; +    } +  } + +  return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; + +FormData.prototype._getContentDisposition = function(value, options) { + +  var filename +    , contentDisposition +    ; + +  if (typeof options.filepath === 'string') { +    // custom filepath for relative paths +    filename = path.normalize(options.filepath).replace(/\\/g, '/'); +  } else if (options.filename || value.name || value.path) { +    // custom filename take precedence +    // formidable and the browser add a name property +    // fs- and request- streams have path property +    filename = path.basename(options.filename || value.name || value.path); +  } else if (value.readable && value.hasOwnProperty('httpVersion')) { +    // or try http response +    filename = path.basename(value.client._httpMessage.path || ''); +  } + +  if (filename) { +    contentDisposition = 'filename="' + filename + '"'; +  } + +  return contentDisposition; +}; + +FormData.prototype._getContentType = function(value, options) { + +  // use custom content-type above all +  var contentType = options.contentType; + +  // or try `name` from formidable, browser +  if (!contentType && value.name) { +    contentType = mime.lookup(value.name); +  } + +  // or try `path` from fs-, request- streams +  if (!contentType && value.path) { +    contentType = mime.lookup(value.path); +  } + +  // or if it's http-reponse +  if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { +    contentType = value.headers['content-type']; +  } + +  // or guess it from the filepath or filename +  if (!contentType && (options.filepath || options.filename)) { +    contentType = mime.lookup(options.filepath || options.filename); +  } + +  // fallback to the default content type if `value` is not simple value +  if (!contentType && typeof value == 'object') { +    contentType = FormData.DEFAULT_CONTENT_TYPE; +  } + +  return contentType; +}; + +FormData.prototype._multiPartFooter = function() { +  return function(next) { +    var footer = FormData.LINE_BREAK; + +    var lastPart = (this._streams.length === 0); +    if (lastPart) { +      footer += this._lastBoundary(); +    } + +    next(footer); +  }.bind(this); +}; + +FormData.prototype._lastBoundary = function() { +  return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; + +FormData.prototype.getHeaders = function(userHeaders) { +  var header; +  var formHeaders = { +    'content-type': 'multipart/form-data; boundary=' + this.getBoundary() +  }; + +  for (header in userHeaders) { +    if (userHeaders.hasOwnProperty(header)) { +      formHeaders[header.toLowerCase()] = userHeaders[header]; +    } +  } + +  return formHeaders; +}; + +FormData.prototype.setBoundary = function(boundary) { +  this._boundary = boundary; +}; + +FormData.prototype.getBoundary = function() { +  if (!this._boundary) { +    this._generateBoundary(); +  } + +  return this._boundary; +}; + +FormData.prototype.getBuffer = function() { +  var dataBuffer = new Buffer.alloc( 0 ); +  var boundary = this.getBoundary(); + +  // Create the form content. Add Line breaks to the end of data. +  for (var i = 0, len = this._streams.length; i < len; i++) { +    if (typeof this._streams[i] !== 'function') { + +      // Add content to the buffer. +      if(Buffer.isBuffer(this._streams[i])) { +        dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); +      }else { +        dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); +      } + +      // Add break after content. +      if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { +        dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); +      } +    } +  } + +  // Add the footer and return the Buffer object. +  return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); +}; + +FormData.prototype._generateBoundary = function() { +  // This generates a 50 character boundary similar to those used by Firefox. +  // They are optimized for boyer-moore parsing. +  var boundary = '--------------------------'; +  for (var i = 0; i < 24; i++) { +    boundary += Math.floor(Math.random() * 10).toString(16); +  } + +  this._boundary = boundary; +}; + +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { +  var knownLength = this._overheadLength + this._valueLength; + +  // Don't get confused, there are 3 "internal" streams for each keyval pair +  // so it basically checks if there is any value added to the form +  if (this._streams.length) { +    knownLength += this._lastBoundary().length; +  } + +  // https://github.com/form-data/form-data/issues/40 +  if (!this.hasKnownLength()) { +    // Some async length retrievers are present +    // therefore synchronous length calculation is false. +    // Please use getLength(callback) to get proper length +    this._error(new Error('Cannot calculate proper length in synchronous way.')); +  } + +  return knownLength; +}; + +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { +  var hasKnownLength = true; + +  if (this._valuesToMeasure.length) { +    hasKnownLength = false; +  } + +  return hasKnownLength; +}; + +FormData.prototype.getLength = function(cb) { +  var knownLength = this._overheadLength + this._valueLength; + +  if (this._streams.length) { +    knownLength += this._lastBoundary().length; +  } + +  if (!this._valuesToMeasure.length) { +    process.nextTick(cb.bind(this, null, knownLength)); +    return; +  } + +  asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { +    if (err) { +      cb(err); +      return; +    } + +    values.forEach(function(length) { +      knownLength += length; +    }); + +    cb(null, knownLength); +  }); +}; + +FormData.prototype.submit = function(params, cb) { +  var request +    , options +    , defaults = {method: 'post'} +    ; + +  // parse provided url if it's string +  // or treat it as options object +  if (typeof params == 'string') { + +    params = parseUrl(params); +    options = populate({ +      port: params.port, +      path: params.pathname, +      host: params.hostname, +      protocol: params.protocol +    }, defaults); + +  // use custom params +  } else { + +    options = populate(params, defaults); +    // if no port provided use default one +    if (!options.port) { +      options.port = options.protocol == 'https:' ? 443 : 80; +    } +  } + +  // put that good code in getHeaders to some use +  options.headers = this.getHeaders(params.headers); + +  // https if specified, fallback to http in any other case +  if (options.protocol == 'https:') { +    request = https.request(options); +  } else { +    request = http.request(options); +  } + +  // get content length and fire away +  this.getLength(function(err, length) { +    if (err) { +      this._error(err); +      return; +    } + +    // add content length +    request.setHeader('Content-Length', length); + +    this.pipe(request); +    if (cb) { +      var onResponse; + +      var callback = function (error, responce) { +        request.removeListener('error', callback); +        request.removeListener('response', onResponse); + +        return cb.call(this, error, responce); +      }; + +      onResponse = callback.bind(this, null); + +      request.on('error', callback); +      request.on('response', onResponse); +    } +  }.bind(this)); + +  return request; +}; + +FormData.prototype._error = function(err) { +  if (!this.error) { +    this.error = err; +    this.pause(); +    this.emit('error', err); +  } +}; + +FormData.prototype.toString = function () { +  return '[object FormData]'; +}; diff --git a/node_modules/form-data/lib/populate.js b/node_modules/form-data/lib/populate.js new file mode 100644 index 0000000..4d35738 --- /dev/null +++ b/node_modules/form-data/lib/populate.js @@ -0,0 +1,10 @@ +// populates missing values +module.exports = function(dst, src) { + +  Object.keys(src).forEach(function(prop) +  { +    dst[prop] = dst[prop] || src[prop]; +  }); + +  return dst; +};  | 
