Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/plugins/octetstream.js
Original file line number Diff line number Diff line change
@@ -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";
Comment on lines +4 to +5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The two separate import statements can be merged into a single combined import, which is the pattern used throughout the codebase (e.g. import FormidableError, * as errors from "./FormidableError.js" in Formidable.js).

Suggested change
import * as errors from "../FormidableError.js";
import FormidableError from "../FormidableError.js";
import FormidableError, * as errors from "../FormidableError.js";

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex Fix in Claude Code


export const octetStreamType = "octet-stream";
// the `options` is also available through the `options` / `formidable.options`
Expand Down Expand Up @@ -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;

Expand Down
38 changes: 38 additions & 0 deletions test/integration/octet-stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,41 @@ test("octet stream", (done) => {
createReadStream(testFilePath).pipe(request);
});
});

test("octet stream enforces maxFileSize", (done) => {
const PORT2 = PORT + 1;
let request;
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();
// The upload was rejected mid-body, so the connection never completes on
// its own; without this the socket outlives the test and Jest's worker.
request.destroy();
server.close();
done();
});
});

server.listen(PORT2, (err) => {
assert(!err, "should not have error, but be falsey");

request = _request({
port: PORT2,
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
},
});

// Destroying the request above surfaces here as ECONNRESET.
request.on("error", () => {});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unexpected request errors disappear The handler ignores every client request error, not just the expected reset after request.destroy(). If the request fails before reaching the server, the parse callback never runs, so the test times out and leaves the server open instead of reporting the connection error and cleaning up.

Fix in Codex Fix in Claude Code

request.end(Buffer.alloc(256 * 1024, 0x42));
});
});
Comment thread
GrosSacASac marked this conversation as resolved.