Skip to content

Commit

Permalink
Add support for storing multipart files metadata (mockoon#1532)
Browse files Browse the repository at this point in the history
Files are *not* saved anywhere, only their metadata are added to the body (filename, type, size and form field)
Closes mockoon#1445
  • Loading branch information
255kb authored Oct 1, 2024
1 parent 7083501 commit ea2695b
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 354 deletions.
40 changes: 37 additions & 3 deletions packages/commons-server/src/libs/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Environment,
FileExtensionsWithTemplating,
GetContentType,
getLatency,
GetRouteResponseContentType,
Header,
IsValidURL,
Expand All @@ -26,6 +25,7 @@ import {
defaultEnvironmentVariablesPrefix,
defaultMaxTransactionLogs,
generateUUID,
getLatency,
stringIncludesArrayItems
} from '@mockoon/commons';
import appendField from 'append-field';
Expand All @@ -50,6 +50,7 @@ import { lookup as mimeTypeLookup } from 'mime-types';
import { basename, extname } from 'path';
import { parse as qsParse } from 'qs';
import rangeParser from 'range-parser';
import { Readable } from 'stream';
import { SecureContextOptions } from 'tls';
import TypedEmitter from 'typed-emitter';
import { parse as parseUrl } from 'url';
Expand Down Expand Up @@ -104,7 +105,9 @@ export class MockoonServer extends (EventEmitter as new () => TypedEmitter<Serve
enableAdminApi: true,
disableTls: false,
maxTransactionLogs: defaultMaxTransactionLogs,
enableRandomLatency: false
enableRandomLatency: false,
maxFileUploads: 10,
maxFileSize: 10 * 1024 * 1024 // 10MB
};
private transactionLogs: Transaction[] = [];

Expand Down Expand Up @@ -371,7 +374,11 @@ export class MockoonServer extends (EventEmitter as new () => TypedEmitter<Serve
} else if (requestContentType.includes('multipart/form-data')) {
const busboyParse = busboy({
headers: request.headers,
limits: { fieldNameSize: 1000, files: 0 }
limits: {
fieldNameSize: 1000,
files: this.options.maxFileUploads,
fileSize: this.options.maxFileSize
}
});

busboyParse.on('field', (name, value, info) => {
Expand All @@ -384,6 +391,33 @@ export class MockoonServer extends (EventEmitter as new () => TypedEmitter<Serve
}
});

busboyParse.on(
'file',
(
name: string,
stream: Readable,
info: { filename: string; encoding: string; mimeType: string }
) => {
if (request.body === undefined) {
request.body = {};
}

const file = {
filename: info.filename,
mimetype: info.mimeType,
size: 0
};

stream.on('data', (data) => {
file.size += data.length;
});

stream.on('close', () => {
appendField(request.body, name, file);
});
}
);

busboyParse.on('error', (error: any) => {
this.emit('error', ServerErrorCodes.REQUEST_BODY_PARSE, error);
// we want to continue answering the call despite the parsing errors
Expand Down
11 changes: 11 additions & 0 deletions packages/commons/src/models/server.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,15 @@ export type ServerOptions = {
* Enable random latency from 0 to value specified in the route settings. |
*/
enableRandomLatency: boolean;

/**
* Max file upload number (multipart/form-data).
* Set to 0 to disable file uploads. (busboy)
*/
maxFileUploads?: number;

/**
* Max file upload size (multipart/form-data).
*/
maxFileSize?: number;
};
Loading

0 comments on commit ea2695b

Please sign in to comment.