Skip to content

Commit

Permalink
Merge pull request m4nuC#53 from alqu/master
Browse files Browse the repository at this point in the history
Update internal busboy from v0.3.1 to v1.4.0
  • Loading branch information
m4nuC authored Nov 18, 2023
2 parents 3da5e7e + 63c2d2e commit c68d7b8
Show file tree
Hide file tree
Showing 9 changed files with 2,869 additions and 1,025 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
node_modules
.nyc_output
coverage
npm-debug.log
node_modules
npm-debug.log
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore artifacts:
coverage
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sudo: false
node_js:
- "10"
- '10'
language: node_js
script: "npm run cover"
after_script: "npm i codecov.io && cat ./coverage/coverage.json | ./node_modules/codecov.io/bin/codecov.io.js"
script: 'npm run cover'
after_script: 'npm i codecov.io && cat ./coverage/coverage.json | ./node_modules/codecov.io/bin/codecov.io.js'
68 changes: 40 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Promise Based Multipart Form Parser


[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
Expand All @@ -22,56 +21,62 @@ Designed for use with [Koa2](https://github.com/koajs/koa/tree/v2.x) and [Async/
## Examples

### Async/Await (using temp files)

```js
import asyncBusboy from 'async-busboy';

// Koa 2 middleware
async function(ctx, next) {
const {files, fields} = await asyncBusboy(ctx.req);
async function someFunction(ctx, next) {
const { files, fields } = await asyncBusboy(ctx.req);

// Make some validation on the fields before upload to S3
if ( checkFiles(fields) ) {
files.map(uploadFilesToS3)
if (checkFiles(fields)) {
files.map(uploadFilesToS3);
} else {
return 'error';
}
}
```

### Async/Await (using custom onFile handler, i.e. no temp files)

```js
import asyncBusboy from 'async-busboy';

// Koa 2 middleware
async function(ctx, next) {
 const { fields } = await asyncBusboy(ctx.req, {
onFile: function(fieldname, file, filename, encoding, mimetype) {
async function someFunction(ctx, next) {
const { fields } = await asyncBusboy(ctx.req, {
onFile: function (fieldname, file, filename, encoding, mimetype) {
uploadFilesToS3(file);
}
},
});

// Do validation, but files are already uploading...
if ( !checkFiles(fields) ) {
if (!checkFiles(fields)) {
return 'error';
}
}
```

### ES5 with promise (using temp files)

```js
var asyncBusboy = require('async-busboy');

function(someHTTPRequest) {
asyncBusboy(someHTTPRequest).then(function(formData) {
function someFunction(someHTTPRequest) {
asyncBusboy(someHTTPRequest).then(function (formData) {
// do something with formData.files
// do someting with formData.fields
});
}
```

## Async API using temp files

The request streams are first written to temporary files using `os.tmpdir()`. File read streams associated with the temporary files are returned from the call to async-busboy. When the consumer has drained the file read streams, the files will be automatically removed, otherwise the host OS should take care of the cleaning process.

## Async API using custom onFile handler

If a custom onFile handler is specified in the options to async-busboy it
will only resolve an object containing fields, but instead no temporary files
needs to be created since the file stream is directly passed to the application.
Expand All @@ -80,22 +85,25 @@ to the implementation of busboy. If you don't care about a received
file stream, simply call `stream.resume()` to discard the content.

## Working with nested inputs and objects

Make sure to serialize objects before sending them as formData.
i.e:
```js

```json5
// Given an object that represent the form data:
{
'field1': 'value',
'objectField': {
'key': 'anotherValue'
field1: 'value',
objectField: {
key: 'anotherValue',
},
'arrayField': ['a', 'b']
arrayField: ['a', 'b'],
//...
};
}
```

Should be sent as:
```

```js
// -> field1[value]
// -> objectField[key][anotherKey]
// -> arrayField[0]['a']
Expand All @@ -104,22 +112,27 @@ Should be sent as:
```

Here is a function that can take care of this process

```js
const serializeFormData = (obj, formDataObj, namespace = null) => {
var formDataObj = formDataObj || {};
var formKey;
for(var property in obj) {
if(obj.hasOwnProperty(property)) {
if(namespace) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (namespace) {
formKey = namespace + '[' + property + ']';
} else {
formKey = property;
}

var value = obj[property];
if(typeof value === 'object' && !(value instanceof File) && !(value instanceof Date)) {
serializeFormData(value, formDataObj, formKey);
} else if(value instanceof Date) {
if (
typeof value === 'object' &&
!(value instanceof File) &&
!(value instanceof Date)
) {
serializeFormData(value, formDataObj, formKey);
} else if (value instanceof Date) {
formDataObj[formKey] = value.toISOString();
} else {
formDataObj[formKey] = value;
Expand All @@ -132,12 +145,11 @@ const serializeFormData = (obj, formDataObj, namespace = null) => {
// -->
```


### Try it on your local

If you want to run some test locally, clone this repo, then run: `node examples/index.js`
From there you can use something like [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) to send `POST` request to `localhost:8080`.
Note: When using Postman make sure to not send a `Content-Type` header, if it's filed by default, just delete it. (This is to let the `boudary` header be generated automaticaly)

Note: When using Postman make sure to not send a `Content-Type` header, if it's filed by default, just delete it. (This is to let the `boudary` header be generated automatically)

### Use cases:

Expand Down
79 changes: 60 additions & 19 deletions examples/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
//This file is if you want to run some test localy, run: `node index.js`
//From there you can use something like [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) to send `POST` request to `localhost:8080`.
//Note: When using Postman make sure to not send a `Content-Type` header, if it's field by default, juste delete it.
// This file is if you want to run some test locally, run: `node index.js`
// From there you can use something like [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) to send `POST` request to `localhost:8080`.
// Note: When using Postman make sure to not send a `Content-Type` header, if it's field by default, juste delete it.

const asyncBusboy = require('../')
const asyncBusboy = require('../');
const http = require('http');
const PORT = 8080;

function handleRequest(request, response){
asyncBusboy(request).then(function(formData) {
// [You can put your tests here]
console.log('Files :', formData.files);
console.log('Fields :', formData.fields)
const server = http
.createServer((req, res) => {
if (req.method === 'POST') {
console.log('POST request');
asyncBusboy(req).then(
function (formData) {
// [You can put your tests here]
console.log('Files :', formData.files);
console.log('Fields :', formData.fields);

// We need to emit a reponse so that the request doesn't hang
response.end('It Works!! ');
},function(error) {
console.log(error)
response.end('Something broke!! ');
// We need to emit a response so that the request doesn't hang
res.end('It Works!! ');
},
function (error) {
console.log(error);
res.end('Something broke!! ');
}
);
} else if (req.method === 'GET') {
res.writeHead(200, { Connection: 'close' });
res.end(`
<!doctype html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Async Busboy upload test</title>
<link rel="stylesheet" href="//unpkg.com/@picocss/pico@latest/css/pico.classless.min.css">
</head>
<body>
<main>
<h1>Async Busboy upload test</h1>
<form method="POST" enctype="multipart/form-data">
<label>
Choose file for upload
<input type="file" name="filefield">
</label>
<label>
A text field
<input type="text" name="textfield" placeholder="a text field">
</label>
<button type="submit">Submit</button>
</form>
</main>
</body>
</html>
`);
}
})
.listen(PORT, () => {
console.log('Server listening on: http://localhost:%s', PORT);
});
}

var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
// Example output:
//
// Server listening on: http://localhost:8080
// < ... form submitted ... >
// POST request
// Files : [ ...
// Fields : { textfield: '...' }
Loading

0 comments on commit c68d7b8

Please sign in to comment.