Skip to content

Fails on duplicate Content-Type headers #29

@jonbarrow

Description

@jonbarrow

According to spec, an HTTP message may contain headers with the same name. In those cases the values of the headers are concatenated into a comma separated list https://datatracker.ietf.org/doc/html/rfc9110#section-5.2:

When a field name is repeated within a section, its combined field value consists of the list of corresponding field line values within that section, concatenated in order, with each field line value separated by a comma.

For example, this section:

Example-Field: Foo, Bar
Example-Field: Baz

contains two field lines, both with the field name "Example-Field". The first field line has a field line value of "Foo, Bar", while the second field line value is "Baz". The field value for "Example-Field" is the list "Foo, Bar, Baz".

However content-type fails to parse values when they are concatenated like this. Basic repro:

const contentType = require('content-type');

let type1;
let type2;

try {
	type1 = contentType.parse('application/x-www-form-urlencoded');
	type2 = contentType.parse('application/x-www-form-urlencoded, application/x-www-form-urlencoded');
} catch {} // Ignore errors

console.log(type1); // ContentType { parameters: [Object: null prototype] {}, type: 'application/x-www-form-urlencoded' }
console.log(type2); // undefined. This threw "invalid media type"

While an uncommon situation, it is one that can happen and is perfectly within the spec. A common way which this may happen is when using Cloudflare Workers/Snippets. If a request comes in and is processed by a Cloudflare Worker/Snippet and contains a duplicate header, Cloudflare will automatically convert this into a comma separated list, and thus fail to be processed here

This is caused by the following regex only allowing a single value for the header:

var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/

This issue is related to several other issues, which I will link here after they are made, since I'm not sure who should have the responsibility of ensuring the header is split correctly

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions