diff --git a/src/plugins/octetstream.js b/src/plugins/octetstream.js index 8a0b2709..2fed2eb5 100644 --- a/src/plugins/octetstream.js +++ b/src/plugins/octetstream.js @@ -1,6 +1,8 @@ /* eslint-disable no-underscore-dangle */ import OctetStreamParser from "../parsers/OctetStream.js"; +import * as errors from "../FormidableError.js"; +import FormidableError from "../FormidableError.js"; export const octetStreamType = "octet-stream"; // the `options` is also available through the `options` / `formidable.options` @@ -47,8 +49,33 @@ async function init(_self, _opts) { // Keep track of writes that haven't finished so we don't emit the file before it's done being written let outstandingWrites = 0; + let fileSize = 0; this._parser.on("data", (buffer) => { + fileSize += buffer.length; + this._totalFileSize += buffer.length; + + if (fileSize > this.options.maxFileSize) { + this._error( + new FormidableError( + `options.maxFileSize (${this.options.maxFileSize} bytes), received ${fileSize} bytes of file data`, + errors.biggerThanMaxFileSize, + 413 + ) + ); + return; + } + if (this._totalFileSize > this.options.maxTotalFileSize) { + this._error( + new FormidableError( + `options.maxTotalFileSize (${this.options.maxTotalFileSize} bytes) exceeded, received ${this._totalFileSize} bytes of file data`, + errors.biggerThanTotalMaxFileSize, + 413 + ) + ); + return; + } + this.pause(); outstandingWrites += 1; diff --git a/test/integration/octet-stream.test.js b/test/integration/octet-stream.test.js index b6b6ab11..bc30743e 100644 --- a/test/integration/octet-stream.test.js +++ b/test/integration/octet-stream.test.js @@ -52,3 +52,35 @@ test("octet stream", (done) => { createReadStream(testFilePath).pipe(request); }); }); + +test("octet stream enforces maxFileSize", (done) => { + const PORT2 = PORT + 1; + const server = createServer((req, res) => { + const form = formidable({ maxFileSize: 1024, maxTotalFileSize: 2048 }); + + form.parse(req, (err, fields, files) => { + // a 256KB octet-stream body must be rejected, not written to disk + assert(err, "expected an error for over-sized octet-stream upload"); + strictEqual(err.code, 1016); // biggerThanMaxFileSize + strictEqual(Object.keys(files).length, 0); + + res.end(); + server.close(); + done(); + }); + }); + + server.listen(PORT2, (err) => { + assert(!err, "should not have error, but be falsey"); + + const request = _request({ + port: PORT2, + method: "POST", + headers: { + "Content-Type": "application/octet-stream", + }, + }); + + request.end(Buffer.alloc(256 * 1024, 0x42)); + }); +});