Skip to content

Commit 83d32d3

Browse files
committed
start accepting multipart form data in /bake
1 parent 81613c1 commit 83d32d3

7 files changed

Lines changed: 107 additions & 8 deletions

File tree

app.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ const app = express();
1616
app.disable("x-powered-by");
1717

1818

19-
if (process.env.NODE_ENV === "production") {
19+
if (process.env.NODE_ENV === "production" || process.env.TEST_LOGGING) {
2020
app.use(pino({
21-
level: "warn"
21+
level: "warn",
22+
prettyPrint: true,
2223
}));
2324
app.use(helmet());
2425
} else {

package-lock.json

Lines changed: 3 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"scripts": {
2727
"nodemon": "nodemon",
2828
"start": "DEBUG=cyberchef-server:server node -r esm ./bin/www",
29-
"test": "mocha -r esm",
29+
"test": "TEST_LOGGING=true mocha -r esm",
3030
"prod": "NODE_ENV=production node -r esm ./bin/www",
3131
"lint": "./node_modules/.bin/eslint --fix .",
3232
"lint-test": "./node_modules/.bin/eslint ."
@@ -38,6 +38,7 @@
3838
"esm": "^3.2.25",
3939
"express": "~4.16.1",
4040
"express-pino-logger": "^4.0.0",
41+
"formidable": "^1.2.2",
4142
"helmet": "^3.21.1",
4243
"swagger-ui-express": "^4.1.2",
4344
"yaml": "^1.7.2"

routes/bake.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,73 @@
11
import { Router } from "express";
2+
import formidable from "formidable";
23
const router = Router();
34
import { bake, Dish } from "cyberchef/src/node/index.mjs";
45

56
/**
67
* bakePost
78
*/
89
router.post("/", async function bakePost(req, res, next) {
10+
if (req.is("multipart/form-data")) {
11+
bakeMultipartForm(req, res, next);
12+
} else {
13+
bakeBody(req, res, next);
14+
}
15+
});
16+
17+
async function bakeMultipartForm(req, res, next) {
18+
const form = formidable();
19+
20+
try {
21+
22+
form.parse(req, async (err, fields, files) => {
23+
24+
// req.log.warn(`Recipe: ${fields.recipe}`);
25+
// req.log.warn(`Input: ${files.input}`);
26+
// req.log.warn(`Other input: ${fields.input}`);
27+
if (err) {
28+
throw err;
29+
}
30+
31+
if (!('recipe' in fields)) {
32+
throw new Error("Could not find required 'recipe' field in multipart form data");
33+
}
34+
35+
let dish;
36+
37+
// Case: data is in files.input
38+
if('input' in files) {
39+
// read the contents of the file and use it as an input
40+
res.json({ fields, files });
41+
} else if ('input' in fields) {
42+
43+
dish = await bake(fields.input, fields.recipe);
44+
45+
} else {
46+
throw new Error("Could not find 'input' field in multipart form data.");
47+
}
48+
49+
// Attempt to translate to another type. Any translation errors
50+
// propagate through to the errorHandler.
51+
if ('outputType' in fields) {
52+
dish.get(req.body.outputType);
53+
}
54+
55+
if (dish) {
56+
res.send({
57+
value: dish.value,
58+
type: Dish.enumLookup(dish.type),
59+
});
60+
}
61+
62+
});
63+
64+
} catch (e) {
65+
next(e);
66+
}
67+
}
68+
69+
async function bakeBody(req, res, next) {
70+
971
try {
1072
if (!req.body.input) {
1173
throw new TypeError("'input' property is required in request body");
@@ -31,6 +93,6 @@ router.post("/", async function bakePost(req, res, next) {
3193
} catch (e) {
3294
next(e);
3395
}
34-
});
96+
}
3597

3698
export default router;

test-input.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
68 65 6c 6c 6f

test/bake.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,37 @@ describe("POST /bake", function() {
208208
});
209209

210210
});
211+
212+
describe("POST /bake files", function () {
213+
it("should take input as a multipart file upload", (done) => {
214+
request(app)
215+
.post("/bake")
216+
.field("recipe", "from hex")
217+
.attach("input", "test/test-hex-input.txt")
218+
.expect(200, done);
219+
});
220+
221+
it("should take input as a multipart field", (done) => {
222+
request(app)
223+
.post("/bake")
224+
.field("recipe", "to morse code")
225+
.field("input", "The crowds stared around wildly")
226+
.expect(200, done);
227+
});
228+
229+
it("should perform a simple recipe with input as a form field", (done) => {
230+
request(app)
231+
.post("/bake")
232+
.field("recipe", "to morse code")
233+
.field("input", "The crowds stared around wildly")
234+
.expect(200)
235+
.expect({
236+
value: `- .... .
237+
-.-. .-. --- .-- -.. ...
238+
... - .- .-. . -..
239+
.- .-. --- ..- -. -..
240+
.-- .. .-.. -.. .-.. -.--`,
241+
type: "string",
242+
}, done);
243+
})
244+
});

test/test-hex-input.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
54 68 65 20 63 72 6f 77 64 73 20 73 74 61 72 65 64 20 61 72 6f 75 6e 64 20 77 69 6c 64 6c 79

0 commit comments

Comments
 (0)