Skip to content

Commit

Permalink
add formidable file upload example
Browse files Browse the repository at this point in the history
  • Loading branch information
icebob committed Oct 8, 2023
1 parent 29280b4 commit 560cd44
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"type": "node",
"request": "launch",
"name": "Launch demo",
"program": "${workspaceRoot}/examples/dev/index.js",
"program": "${file}",
"cwd": "${workspaceRoot}",
"env": {
"PORT": "3000"
Expand Down
4 changes: 2 additions & 2 deletions examples/file/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use strict";

/**
* This example demonstrates how to upload files to API Gateway
* This example demonstrates how to upload files to API Gateway with built-in busboy
*
* Example:
*
* - File upload:
* Open https://localhost:4000/upload.html in the browser and upload a file. The file will be placed to the "examples/__uploads" folder.
* Open http://localhost:3000/ in the browser and upload a file. The file will be placed to the "examples/__uploads" folder.
*
* - or upload file with cURL
* curl -X PUT -H "Content-Type: image/png" --data-binary @test.png http://localhost:3000/upload
Expand Down
73 changes: 73 additions & 0 deletions examples/formidable/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File upload test</title>

<style>
body {
font-family: Arial, sans-serif;
font-size: 16px;
}
button, input[type="submit"] {
margin-top: 10px;
padding: 0.25em 1em;
}

fieldset {
margin: 1em;
}
</style>
</head>
<body>
<fieldset>
<legend>Single file upload</legend>
<form action="/upload/single/1234" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" value="Test User">
<p>Select image to upload:</p>
<input type="file" name="myfile" id="myfile">
<br/>
<input type="submit" value="Upload one image" name="submit">
</form>
</fieldset>
<fieldset>
<legend>Multiple file upload</legend>
<form action="/upload/multi" method="post" enctype="multipart/form-data">
<p>Select image to upload:</p>
<input type="file" name="myfile" id="myfile" multiple>
<br/>
<input type="submit" value="Upload multiple images" name="submit">
</form>
</fieldset>
<fieldset>
<legend>Upload with AJAX</legend>
<p>Select image to upload:</p>
<input type="file" name="myJSFile" id="myJSFile">
<br/>
<button onclick="uploadPut('/upload/1234')">Upload one image via AJAX</button>
<p id="responseOK" style="color: green; font-weight: bold"></p>
<p id="responseError" style="color: red; font-weight: bold"></p>
</fieldset>
</body>
<script>
function uploadPut(postUrl)
{
const input = document.querySelector("#myJSFile");
const pOK = document.querySelector("#responseOK");
const pError = document.querySelector("#responseError");
pOK.innerHTML = "";
pError.innerHTML = "";

var req = new XMLHttpRequest();
req.open("PUT", postUrl);
req.setRequestHeader("Content-type", "image/png");
req.onload = function(event) {
if (event.target.status == 200)
return pOK.innerHTML ="Uploaded successfully! " + event.target.responseText;

pError.innerHTML = "Upload error: " + event.target.responseText;
}
req.send(input.files[0]);
}
</script>
</html>
114 changes: 114 additions & 0 deletions examples/formidable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"use strict";

/**
* This example demonstrates how to upload files to API Gateway with Formidable
*
* Example:
*
* - File upload:
* Open http://localhost:3000 in the browser and upload a file. The file will be placed to the "examples/__uploads" folder.
*
* - or upload file with cURL
* curl -X PUT -H "Content-Type: image/png" --data-binary @test.png http://localhost:3000/upload
*
* - or upload file with cURL and params
* curl -X PUT -H "Content-Type: image/png" --data-binary @test.png http://localhost:3000/upload/d5a41a5b-28a8-4795-bc8a-e48dae5ebdb3
*/

const fs = require("fs");
const { ServiceBroker } = require("moleculer");
const formidable = require("formidable");

// ----

const ApiGatewayService = require("../../index");

// Create broker
const broker = new ServiceBroker({});

broker.loadService("./examples/file.service.js");

// Load API Gateway
broker.createService({
mixins: [ApiGatewayService],
settings: {
path: "/upload",

routes: [
{
path: "",

// You should disable body parsers
bodyParsers: {
json: false,
urlencoded: false
},

aliases: {
// File upload from AJAX or cURL
"PUT /": "stream:file.save",

// File upload from AJAX or cURL with params
"PUT /:id": "stream:file.save",

"POST /single/:id"(req, res) {
return this.handleFileUpload(req, res);
},

// File upload from HTML form
"POST /multi"(req, res) {
return this.handleFileUpload(req, res);
},
},

callOptions: {
meta: {
a: 5
}
},

mappingPolicy: "restrict"
},

],

assets: {
folder: "./examples/formidable/assets",
}
},

methods: {
handleFileUpload(req, res) {
// parse a file upload
const form = new formidable.IncomingForm();
form.multiples = true;

form.parse(req, async (err, fields, files) => {
if (err) {
this.logger.error(err);
return this.sendError(req, res, err);
}

const ctx = req.$ctx;
const entries = Array.isArray(files.myfile) ? files.myfile : [files.myfile];
const result = await Promise.all(entries.map(entry => {
return ctx.call("file.save", fs.createReadStream(entry.path), {
meta: {
filename: entry.name,
$params: {
...req.params,
...fields,
}
}
});
}));

return this.sendResponse(req, res, Array.isArray(files.myfile) ? result : result[0]);
});

}
}
});

// Start server
broker.start();
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"eslint-plugin-security": "^1.4.0",
"express": "^4.17.1",
"fakerator": "^0.3.4",
"formidable": "^1.2.6",
"jest": "^27.2.5",
"jest-cli": "^27.2.5",
"jsonwebtoken": "^8.5.1",
Expand Down

0 comments on commit 560cd44

Please sign in to comment.