Repository: expressjs/connect-multiparty
Branch: master
Commit: 7c50f097dcc7
Files: 11
Total size: 17.2 KB
Directory structure:
gitextract_6_3s62n3/
├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .travis.yml
├── HISTORY.md
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
└── multipart.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true
[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
[{*.js,*.json,*.yml}]
indent_size = 2
indent_style = space
================================================
FILE: .eslintignore
================================================
coverage
node_modules
================================================
FILE: .eslintrc.yml
================================================
rules:
eol-last: error
indent: ["error", 2, { "SwitchCase": 1 }]
no-trailing-spaces: error
================================================
FILE: .gitignore
================================================
.nyc_output/
coverage/
node_modules/
npm-debug.log
package-lock.json
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- "0.10"
- "4.9"
- "6.17"
- "8.16"
- "10.16"
- "12.11"
sudo: false
cache:
directories:
- node_modules
before_install:
# Configure npm
- |
# Skip updating shrinkwrap / lock
npm config set shrinkwrap false
# Setup Node.js version-specific dependencies
- |
# eslint for linting
# - remove for Node.js < 8
if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 8 ]]; then
npm rm --save-dev eslint
fi
- |
# mocha for testing
# - use 3.x for Node.js < 4
# - use 5.x for Node.js < 6
if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
npm install --save-dev mocha@3.5.3
elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
npm install --save-dev mocha@5.2.0
fi
- |
# nyc for coverage
# - use 10.x for Node.js < 4
# - use 11.x for Node.js < 6
if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
npm install --save-dev nyc@10.3.2
elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
npm install --save-dev nyc@11.9.0
fi
- |
# supertest for http calls
# - use 2.0.0 for Node.js < 4
# - use 3.4.2 for Node.js < 6
if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
npm install --save-dev supertest@2.0.0
elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
npm install --save-dev supertest@3.4.2
fi
# Update Node.js modules
- |
# Prune & rebuild node_modules
if [[ -d node_modules ]]; then
npm prune
npm rebuild
fi
script:
- |
# Run test script
npm run-script test-ci
- |
# Run linting
if npm -ps ls eslint | grep -q eslint; then
npm run-script lint
fi
after_script:
- |
# Upload coverage to coveralls, if exists
if [[ -d .nyc_output ]]; then
npm install --save-dev coveralls@2
nyc report --reporter=text-lcov | coveralls
fi
================================================
FILE: HISTORY.md
================================================
unreleased
==========
* deps: http-errors@~1.7.3
- Fix error creating objects in some environments
- deps: inherits@2.0.4
- deps: setprototypeof@1.1.1
* deps: qs@~6.7.0
- Fix parsing array brackets after index
* deps: safe-buffer@5.2.0
* deps: type-is@~1.6.18
- deps: mime-types@~2.1.24
- perf: prevent internal `throw` on invalid type
2.2.0 / 2018-09-14
==================
* Fix masking `multiparty` errors as 400
* deps: multiparty@~4.2.1
- Use http-errors for raised errors
- Use uid-safe module to for temp file names
- Update to fd-slicer 1.1.0
- perf: remove parameter reassignment
2.1.1 / 2018-06-22
==================
* deps: multiparty@~4.1.4
- Enable strict mode
- Fix file extension filtering stopping on certain whitespace characters
- Use safe-buffer for improved API safety
* deps: qs@~6.5.2
* deps: type-is@~1.6.16
- deps: mime-types@~2.1.18
2.1.0 / 2017-10-19
==================
* deps: multiparty@~4.1.3
- Use `os.tmpdir()` instead of `os.tmpDir()`
- deps: fd-slicer@~1.0.1
* deps: qs@~6.5.1
- Fix array parsing from skipping empty values
- Fix compacting of nested sparse arrays
- Fix parsing & compacting very deep objects
* deps: type-is@~1.6.15
- Fix type error when given invalid type to match against
- deps: mime-types@~2.1.15
* perf: enable strict mode
2.0.0 / 2015-07-13
==================
* Requires Node.js >= 0.10.0
* deps: multiparty@~4.1.2
* deps: on-finished@~2.3.0
* deps: qs@~4.0.0
* deps: type-is@~1.6.4
1.2.5 / 2014-10-14
==================
* Update qs to 2.2.4
* Update type-is to 1.5.2
1.2.4 / 2014-08-29
==================
* Update qs to 2.2.2
1.2.3 / 2014-08-28
==================
* Update qs to 2.2.1
1.2.2 / 2014-08-27
==================
* Update qs to 2.2.0
1.2.1 / 2014-08-07
==================
* Update multiparty to 3.3.2
* Update qs to 1.2.0
1.2.0 / 2014-08-06
==================
* Update multiparty to 3.3.1
* Update qs to 1.1.0
1.1.0 / 2014-07-03
==================
* Update multiparty to 3.3.0
* Use type-is to check Content-Type
1.0.6 / 2014-07-03
==================
* Fix callback hang in node.js 0.8 on errors
1.0.5 / 2014-06-01
==================
* Update multiparty to 3.2.8
1.0.4 / 2014-05-26
==================
* Fix error causing response to hang
* Update multiparty to 3.2.6
1.0.3 / 2014-01-20
==================
* Update multiparty to 3.2
1.0.2 / 2014-01-17
==================
* Update multiparty to 3.1
1.0.1 / 2013-10-25
==================
* Update multiparty to 3.0
1.0.0 / 2013-10-25
==================
* revive
================================================
FILE: LICENSE
================================================
(The MIT License)
Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 TJ Holowaychuk
Copyright (c) 2013 Andrew Kelley
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
> [!CAUTION]
> **This repository is archived and no longer actively maintained.**
>
> We are no longer accepting issues, feature requests, or pull requests.
> For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions).
# connect-multiparty
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[connect](https://github.com/senchalabs/connect/) middleware for
[multiparty](https://github.com/andrewrk/node-multiparty/).
I actually recommend against using this module. It's cleaner to use the
multiparty API directly.
This middleware will create temp files on your server and never clean them
up. Thus you should not add this middleware to all routes; only to the ones
in which you want to accept uploads. And in these endpoints, be sure to
delete all temp files, even the ones that you don't use.
## Usage
```js
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.post('/upload', multipartMiddleware, function(req, resp) {
console.log(req.body, req.files);
// don't forget to delete all req.files when done
});
```
If you pass options to `multipart()`, they are passed directly into
multiparty.
## License
[MIT](LICENSE)
[coveralls-image]: https://img.shields.io/coveralls/expressjs/connect-multiparty/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/connect-multiparty?branch=master
[downloads-image]: https://img.shields.io/npm/dm/connect-multiparty.svg
[downloads-url]: https://npmjs.org/package/connect-multiparty
[npm-image]: https://img.shields.io/npm/v/connect-multiparty.svg
[npm-url]: https://npmjs.org/package/connect-multiparty
[travis-image]: https://img.shields.io/travis/expressjs/connect-multiparty/master.svg
[travis-url]: https://travis-ci.org/expressjs/connect-multiparty
================================================
FILE: index.js
================================================
/*!
* connect-multiparty
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2013 Andrew Kelley
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var multiparty = require('multiparty');
var onFinished = require('on-finished');
var qs = require('qs');
var typeis = require('type-is');
/**
* Module exports.
* @public
*/
module.exports = multipart
/**
* Parse multipart/form-data request bodies, providing the parsed
* object as `req.body` and `req.files`.
*
* The options passed are merged with [multiparty](https://github.com/pillarjs/multiparty)'s
* `Form` object, allowing you to configure the upload directory,
* size limits, etc. For example if you wish to change the upload
* dir do the following:
*
* app.use(multipart({ uploadDir: path }))
*
* @param {Object} options
* @return {Function}
* @public
*/
function multipart (options) {
options = options || {};
return function multipart(req, res, next) {
if (req._body) return next();
req.body = req.body || {};
req.files = req.files || {};
// ignore GET
if ('GET' === req.method || 'HEAD' === req.method) return next();
// check Content-Type
if (!typeis(req, 'multipart/form-data')) return next();
// flag as parsed
req._body = true;
// parse
var form = new multiparty.Form(options);
var data = {};
var files = {};
var done = false;
function ondata(name, val, data){
if (Array.isArray(data[name])) {
data[name].push(val);
} else if (data[name]) {
data[name] = [data[name], val];
} else {
data[name] = val;
}
}
form.on('field', function(name, val){
ondata(name, val, data);
});
form.on('file', function(name, val){
val.name = val.originalFilename;
val.type = val.headers['content-type'] || null;
ondata(name, val, files);
});
form.on('error', function(err){
if (done) return;
done = true;
// set status code on error
var error = createError(400, err)
if (!req.readable) return next(error)
// read off entire request
req.resume();
onFinished(req, function(){
next(error)
});
});
form.on('close', function() {
if (done) return;
done = true;
// expand names with qs & assign
req.body = qs.parse(data, { allowDots: true })
req.files = qs.parse(files, { allowDots: true })
next()
});
form.parse(req);
}
};
================================================
FILE: package.json
================================================
{
"name": "connect-multiparty",
"version": "2.2.0",
"description": "multipart parsing middleware for connect using multiparty",
"author": "Andrew Kelley <superjoe30@gmail.com>",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
],
"license": "MIT",
"repository": "expressjs/connect-multiparty",
"dependencies": {
"http-errors": "~1.7.3",
"multiparty": "~4.2.1",
"on-finished": "~2.3.0",
"qs": "~6.7.0",
"type-is": "~1.6.18"
},
"engines": {
"node": ">=0.10.0"
},
"devDependencies": {
"connect": "3.7.0",
"deep-equal": "1.0.1",
"eslint": "6.5.1",
"mocha": "6.2.1",
"nyc": "14.1.1",
"safe-buffer": "5.2.0",
"supertest": "4.0.2"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"index.js"
],
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec",
"test-ci": "nyc --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}
================================================
FILE: test/multipart.js
================================================
process.env.NODE_ENV = 'test';
var Buffer = require('safe-buffer').Buffer
var connect = require('connect');
var deepEqual = require('deep-equal')
var multipart = require('..');
var request = require('supertest');
describe('multipart()', function(){
it('should ignore GET', function(done){
request(createServer())
.get('/body')
.field('user', 'Tobi')
.expect(200, {}, done)
})
describe('with multipart/form-data', function(){
it('should populate req.body', function(done){
request(createServer())
.post('/body')
.field('user', 'Tobi')
.expect(200, { user: 'Tobi' }, done)
})
it('should handle duplicated middleware', function (done) {
var app = connect()
.use(multipart())
.use(multipart())
.use(function (req, res) {
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(req.body))
})
request(app)
.post('/body')
.field('user', 'Tobi')
.expect(200, { user: 'Tobi' }, done)
})
it('should support files', function(done){
request(createServer())
.post('/files')
.attach('text', Buffer.from('some text here'), 'foo.txt')
.expect(200)
.expect(shouldDeepIncludeInBody({
text: {
name: 'foo.txt',
originalFilename: 'foo.txt',
size: 14,
type: 'text/plain'
}
}))
.end(done)
})
it('should work with multiple fields', function(done){
request(createServer())
.post('/body')
.field('user', 'Tobi')
.field('age', '1')
.expect(200, { user: 'Tobi', age: '1' }, done)
})
it('should handle duplicated fields', function (done) {
request(createServer())
.post('/body')
.field('user', 'Tobi')
.field('user', 'Loki')
.field('user', 'Poki')
.expect(200, { user: [ 'Tobi', 'Loki', 'Poki' ] }, done)
})
it('should support nesting', function(done){
request(createServer())
.post('/body')
.field('user[name][first]', 'tobi')
.field('user[name][last]', 'holowaychuk')
.field('user[age]', '1')
.field('species', 'ferret')
.expect(200, {
species: 'ferret',
user: {
age: '1',
name: { first: 'tobi', last: 'holowaychuk' }
}
}, done)
})
it('should support multiple files of the same name', function(done){
request(createServer())
.post('/files')
.attach('text', Buffer.from('some text here'), 'foo.txt')
.attach('text', Buffer.from('some more text stuff'), 'bar.txt')
.expect(200)
.expect(shouldDeepIncludeInBody({
text: [
{ name: 'foo.txt' },
{ name: 'bar.txt' }
]
}))
.end(done)
})
it('should support nested files', function(done){
request(createServer())
.post('/files')
.attach('docs[foo]', Buffer.from('some text here'), 'foo.txt')
.attach('docs[bar]', Buffer.from('some more text stuff'), 'bar.txt')
.expect(200)
.expect(shouldDeepIncludeInBody({
docs: {
foo: { name: 'foo.txt' },
bar: { name: 'bar.txt' }
}
}))
.end(done)
})
it('should next(err) on multipart failure', function(done){
var app = createServer()
var test = request(app).post('/')
test.set('Content-Type', 'multipart/form-data; boundary=foo');
test.write('--foo\r\n');
test.write('Content-filename="foo.txt"\r\n');
test.write('\r\n');
test.write('some text here');
test.write('Content-Disposition: form-data; name="text"; filename="bar.txt"\r\n');
test.write('\r\n');
test.write('some more text stuff');
test.write('\r\n--foo--');
test.expect(400, 'BadRequestError: Expected alphabetic character, received 61', done)
})
it('should not hang request on failure', function(done){
var app = createServer()
var buf = Buffer.alloc(1024 * 10, '.')
var test = request(app).post('/')
test.set('Content-Type', 'multipart/form-data; boundary=foo');
test.write('--foo\r\n');
test.write('Content-filename="foo.txt"\r\n');
test.write('\r\n');
test.write('some text here');
test.write('Content-Disposition: form-data; name="text"; filename="bar.txt"\r\n');
test.write('\r\n');
test.write('some more text stuff');
test.write('\r\n--foo--');
test.write(buf)
test.write(buf)
test.write(buf)
test.expect(400, 'BadRequestError: Expected alphabetic character, received 61', done)
})
it('should default req.files to {}', function(done){
request(createServer())
.post('/body')
.expect(200, {}, done)
})
it('should return 413 on maxFilesSize exceeded', function (done) {
var max = Math.pow(2, 9)
request(createServer({ maxFilesSize: max }))
.post('/files')
.field('user[name]', 'Tobi')
.attach('text', Buffer.alloc(max + 1, 'x'), 'foo.txt')
.expect(413, done)
})
})
})
function createServer (opts) {
var app = connect()
app.use(multipart(opts))
app.use('/body', function (req, res) {
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(req.body))
})
app.use('/files', function (req, res) {
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(req.files))
})
app.use(function (err, req, res, next) {
res.statusCode = err.statusCode || err.status || 500
res.end(err.name + ': ' + err.message)
})
return app
}
function shouldDeepIncludeInBody (obj) {
return function (res) {
deepEqual(res.body, obj)
}
}
gitextract_6_3s62n3/
├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .travis.yml
├── HISTORY.md
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
└── multipart.js
SYMBOL INDEX (3 symbols across 2 files)
FILE: index.js
function multipart (line 45) | function multipart (options) {
FILE: test/multipart.js
function createServer (line 174) | function createServer (opts) {
function shouldDeepIncludeInBody (line 197) | function shouldDeepIncludeInBody (obj) {
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
{
"path": ".editorconfig",
"chars": 179,
"preview": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n"
},
{
"path": ".eslintignore",
"chars": 22,
"preview": "coverage\nnode_modules\n"
},
{
"path": ".eslintrc.yml",
"chars": 97,
"preview": "rules:\n eol-last: error\n indent: [\"error\", 2, { \"SwitchCase\": 1 }]\n no-trailing-spaces: error\n"
},
{
"path": ".gitignore",
"chars": 69,
"preview": ".nyc_output/\ncoverage/\nnode_modules/\nnpm-debug.log\npackage-lock.json\n"
},
{
"path": ".travis.yml",
"chars": 1976,
"preview": "language: node_js\nnode_js:\n - \"0.10\"\n - \"4.9\"\n - \"6.17\"\n - \"8.16\"\n - \"10.16\"\n - \"12.11\"\nsudo: false\ncache:\n direc"
},
{
"path": "HISTORY.md",
"chars": 2674,
"preview": "unreleased\n==========\n\n * deps: http-errors@~1.7.3\n - Fix error creating objects in some environments\n - deps: "
},
{
"path": "LICENSE",
"chars": 1141,
"preview": "(The MIT License)\n\nCopyright (c) 2010 Sencha Inc.\nCopyright (c) 2011 TJ Holowaychuk\nCopyright (c) 2013 Andrew Kelley\n\nPe"
},
{
"path": "README.md",
"chars": 1958,
"preview": "> [!CAUTION]\n> **This repository is archived and no longer actively maintained.**\n>\n> We are no longer accepting issues,"
},
{
"path": "index.js",
"chars": 2579,
"preview": "/*!\n * connect-multiparty\n * Copyright(c) 2010 Sencha Inc.\n * Copyright(c) 2011 TJ Holowaychuk\n * Copyright(c) 2013 Andr"
},
{
"path": "package.json",
"chars": 1009,
"preview": "{\n \"name\": \"connect-multiparty\",\n \"version\": \"2.2.0\",\n \"description\": \"multipart parsing middleware for connect using"
},
{
"path": "test/multipart.js",
"chars": 5906,
"preview": "\nprocess.env.NODE_ENV = 'test';\n\nvar Buffer = require('safe-buffer').Buffer\nvar connect = require('connect');\nvar deepEq"
}
]
About this extraction
This page contains the full source code of the expressjs/connect-multiparty GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (17.2 KB), approximately 5.3k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.