Skip to content

Use content-type fast parse - #472

Closed
blakeembrey wants to merge 1 commit into
fastify:mainfrom
blakeembrey:be/use-content-type
Closed

Use content-type fast parse#472
blakeembrey wants to merge 1 commit into
fastify:mainfrom
blakeembrey:be/use-content-type

Conversation

@blakeembrey

Copy link
Copy Markdown

Preamble: I know fast-content-type-parse is intended to be a Fastify fork of content-type and is likely forked for historical reasons, but I recently released a content-type@2 and the changes seemed relevant to this package. Mostly because there's no need to parse parameters at all.

Changes fast-content-type-parse to use content-type with parameters: false to extract the content-type parameter.

However, the parser in content-type no longer validates during parse (designed to be lenient/fast) so there is a minor behavior change with invalid MIME types. If you sent something like foo it would currently throw during .parse but in this change it'll forward foo along.

Checklist

@blakeembrey

Copy link
Copy Markdown
Author

@mcollina Is this something that would be useful? The perf benchmarks in the library itself show a substantial improvement:

Benchmarking: "application/json; charset="utf-8""
util#MIMEType x 4,476,603 ops/sec ±2.85% (93 runs sampled)
fast-content-type-parse#parse x 4,891,585 ops/sec ±0.87% (94 runs sampled)
fast-content-type-parse#safeParse x 4,919,872 ops/sec ±0.40% (99 runs sampled)
content-type#parse x 7,153,657 ops/sec ±0.24% (95 runs sampled)
busboy#parseContentType x 1,050,032 ops/sec ±0.97% (97 runs sampled)
Fastest is content-type#parse

And when you skip parameters altogether it's much faster. I've also been working to switch over some other packages in jshttp to use content-type since the perf gain is appreciable and centralizing the behavior has been helpful (e.g. negotiator, type-is)

@blakeembrey

Copy link
Copy Markdown
Author

Maybe a more representative version using parameters: false (not available for the other libs):

Benchmarking: "application/json; charset="utf-8""
util#MIMEType x 4,284,164 ops/sec ±0.84% (95 runs sampled)
fast-content-type-parse#parse x 4,449,273 ops/sec ±0.47% (96 runs sampled)
fast-content-type-parse#safeParse x 4,495,523 ops/sec ±0.25% (98 runs sampled)
content-type#parse x 53,416,459 ops/sec ±1.65% (90 runs sampled)
busboy#parseContentType x 1,019,507 ops/sec ±0.24% (100 runs sampled)
Fastest is content-type#parse

10x bump, and validation of it matching a valid MIME isn't useful because you already have the allowlist as contentTypesToEncode.

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the behavior change can cause possible security issues, and I would hold for now.

@blakeembrey

blakeembrey commented Aug 21, 2026

Copy link
Copy Markdown
Author

@mcollina If you want the type to be validated like the existing code path, and we'd still have improved performance due to the skipping of parameters and improvements to the parser. Would that be suitable?

Edit: It doesn't do that by default because an audit of usages showed they mostly validated twice (e.g. by using something like type-is, negotiator, string comparison, etc).

@blakeembrey

Copy link
Copy Markdown
Author

Just saw fastify/fast-content-type-parse#81, I can close this out.

@blakeembrey
blakeembrey deleted the be/use-content-type branch August 21, 2026 17:34
@blakeembrey

Copy link
Copy Markdown
Author

For context, I've been trying to find upstream dependents that forked from jshttp/pillarjs packages and find ways to merge them back inline for ecosystem performance and security. I'd love to try and continue that with Fastify if you want to land changes like the above into content-type instead of the fork, but I understand either approach.

@mcollina

Copy link
Copy Markdown
Member

The problem is that much of the logic in Fastify assumes the media types are validated. We have been receiving a constant stream of media-type-related vulnerabilities at this point.

We could theoretically move back to content-type, but out of caution we should that across the whole org and part of the next major.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants