diff options
Diffstat (limited to 'together/node_modules/formidable/src/plugins/multipart.js')
-rw-r--r-- | together/node_modules/formidable/src/plugins/multipart.js | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/together/node_modules/formidable/src/plugins/multipart.js b/together/node_modules/formidable/src/plugins/multipart.js deleted file mode 100644 index ba07373..0000000 --- a/together/node_modules/formidable/src/plugins/multipart.js +++ /dev/null @@ -1,173 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -'use strict'; - -const { Stream } = require('stream'); -const MultipartParser = require('../parsers/Multipart'); -const errors = require('../FormidableError.js'); - -const { FormidableError } = errors; - -// the `options` is also available through the `options` / `formidable.options` -module.exports = function plugin(formidable, options) { - // the `this` context is always formidable, as the first argument of a plugin - // but this allows us to customize/test each plugin - - /* istanbul ignore next */ - const self = this || formidable; - - // NOTE: we (currently) support both multipart/form-data and multipart/related - const multipart = /multipart/i.test(self.headers['content-type']); - - if (multipart) { - const m = self.headers['content-type'].match( - /boundary=(?:"([^"]+)"|([^;]+))/i, - ); - if (m) { - const initMultipart = createInitMultipart(m[1] || m[2]); - initMultipart.call(self, self, options); // lgtm [js/superfluous-trailing-arguments] - } else { - const err = new FormidableError( - 'bad content-type header, no multipart boundary', - errors.missingMultipartBoundary, - 400, - ); - self._error(err); - } - } -}; - -// Note that it's a good practice (but it's up to you) to use the `this.options` instead -// of the passed `options` (second) param, because when you decide -// to test the plugin you can pass custom `this` context to it (and so `this.options`) -function createInitMultipart(boundary) { - return function initMultipart() { - this.type = 'multipart'; - - const parser = new MultipartParser(this.options); - let headerField; - let headerValue; - let part; - - parser.initWithBoundary(boundary); - - // eslint-disable-next-line max-statements, consistent-return - parser.on('data', ({ name, buffer, start, end }) => { - if (name === 'partBegin') { - part = new Stream(); - part.readable = true; - part.headers = {}; - part.name = null; - part.originalFilename = null; - part.mimetype = null; - - part.transferEncoding = this.options.encoding; - part.transferBuffer = ''; - - headerField = ''; - headerValue = ''; - } else if (name === 'headerField') { - headerField += buffer.toString(this.options.encoding, start, end); - } else if (name === 'headerValue') { - headerValue += buffer.toString(this.options.encoding, start, end); - } else if (name === 'headerEnd') { - headerField = headerField.toLowerCase(); - part.headers[headerField] = headerValue; - - // matches either a quoted-string or a token (RFC 2616 section 19.5.1) - const m = headerValue.match( - // eslint-disable-next-line no-useless-escape - /\bname=("([^"]*)"|([^\(\)<>@,;:\\"\/\[\]\?=\{\}\s\t/]+))/i, - ); - if (headerField === 'content-disposition') { - if (m) { - part.name = m[2] || m[3] || ''; - } - - part.originalFilename = this._getFileName(headerValue); - } else if (headerField === 'content-type') { - part.mimetype = headerValue; - } else if (headerField === 'content-transfer-encoding') { - part.transferEncoding = headerValue.toLowerCase(); - } - - headerField = ''; - headerValue = ''; - } else if (name === 'headersEnd') { - switch (part.transferEncoding) { - case 'binary': - case '7bit': - case '8bit': - case 'utf-8': { - const dataPropagation = (ctx) => { - if (ctx.name === 'partData') { - part.emit('data', ctx.buffer.slice(ctx.start, ctx.end)); - } - }; - const dataStopPropagation = (ctx) => { - if (ctx.name === 'partEnd') { - part.emit('end'); - parser.off('data', dataPropagation); - parser.off('data', dataStopPropagation); - } - }; - parser.on('data', dataPropagation); - parser.on('data', dataStopPropagation); - break; - } - case 'base64': { - const dataPropagation = (ctx) => { - if (ctx.name === 'partData') { - part.transferBuffer += ctx.buffer - .slice(ctx.start, ctx.end) - .toString('ascii'); - - /* - four bytes (chars) in base64 converts to three bytes in binary - encoding. So we should always work with a number of bytes that - can be divided by 4, it will result in a number of buytes that - can be divided vy 3. - */ - const offset = parseInt(part.transferBuffer.length / 4, 10) * 4; - part.emit( - 'data', - Buffer.from( - part.transferBuffer.substring(0, offset), - 'base64', - ), - ); - part.transferBuffer = part.transferBuffer.substring(offset); - } - }; - const dataStopPropagation = (ctx) => { - if (ctx.name === 'partEnd') { - part.emit('data', Buffer.from(part.transferBuffer, 'base64')); - part.emit('end'); - parser.off('data', dataPropagation); - parser.off('data', dataStopPropagation); - } - }; - parser.on('data', dataPropagation); - parser.on('data', dataStopPropagation); - break; - } - default: - return this._error( - new FormidableError( - 'unknown transfer-encoding', - errors.unknownTransferEncoding, - 501, - ), - ); - } - - this.onPart(part); - } else if (name === 'end') { - this.ended = true; - this._maybeEnd(); - } - }); - - this._parser = parser; - }; -} |