cleanup(web, fetch): dedupe minesniff / "extract a MIME type" algorithm (#14044)

Closes #14002
This commit is contained in:
Andreu Botella 2022-03-20 14:31:12 +01:00 committed by GitHub
parent 0bc286ab47
commit 593801e265
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 71 deletions

View file

@ -18,7 +18,7 @@
const { guardFromHeaders } = window.__bootstrap.headers;
const { mixinBody, extractBody } = window.__bootstrap.fetchBody;
const { getLocationHref } = window.__bootstrap.location;
const mimesniff = window.__bootstrap.mimesniff;
const { extractMimeType } = window.__bootstrap.mimesniff;
const { blobFromObjectUrl } = window.__bootstrap.file;
const {
headersFromHeaderList,
@ -32,9 +32,6 @@
ArrayPrototypeMap,
ArrayPrototypeSlice,
ArrayPrototypeSplice,
MapPrototypeHas,
MapPrototypeGet,
MapPrototypeSet,
ObjectKeys,
ObjectPrototypeIsPrototypeOf,
RegExpPrototypeTest,
@ -174,41 +171,11 @@
/** @type {AbortSignal} */
[_signal];
get [_mimeType]() {
let charset = null;
let essence = null;
let mimeType = null;
const values = getDecodeSplitHeader(
headerListFromHeaders(this[_headers]),
"Content-Type",
);
if (values === null) return null;
for (const value of values) {
const temporaryMimeType = mimesniff.parseMimeType(value);
if (
temporaryMimeType === null ||
mimesniff.essence(temporaryMimeType) == "*/*"
) {
continue;
}
mimeType = temporaryMimeType;
if (mimesniff.essence(mimeType) !== essence) {
charset = null;
const newCharset = MapPrototypeGet(mimeType.parameters, "charset");
if (newCharset !== undefined) {
charset = newCharset;
}
essence = mimesniff.essence(mimeType);
} else {
if (
MapPrototypeHas(mimeType.parameters, "charset") === null &&
charset !== null
) {
MapPrototypeSet(mimeType.parameters, "charset", charset);
}
}
}
if (mimeType === null) return null;
return mimeType;
return extractMimeType(values);
}
get [_body]() {
return this[_request].body;

View file

@ -18,7 +18,7 @@
const { HTTP_TAB_OR_SPACE, regexMatcher } = window.__bootstrap.infra;
const { extractBody, mixinBody } = window.__bootstrap.fetchBody;
const { getLocationHref } = window.__bootstrap.location;
const mimesniff = window.__bootstrap.mimesniff;
const { extractMimeType } = window.__bootstrap.mimesniff;
const { URL } = window.__bootstrap.url;
const {
getDecodeSplitHeader,
@ -30,9 +30,6 @@
const {
ArrayPrototypeMap,
ArrayPrototypePush,
MapPrototypeHas,
MapPrototypeGet,
MapPrototypeSet,
ObjectPrototypeIsPrototypeOf,
RangeError,
RegExp,
@ -162,41 +159,11 @@
class Response {
get [_mimeType]() {
let charset = null;
let essence = null;
let mimeType = null;
const values = getDecodeSplitHeader(
headerListFromHeaders(this[_headers]),
"Content-Type",
);
if (values === null) return null;
for (const value of values) {
const temporaryMimeType = mimesniff.parseMimeType(value);
if (
temporaryMimeType === null ||
mimesniff.essence(temporaryMimeType) == "*/*"
) {
continue;
}
mimeType = temporaryMimeType;
if (mimesniff.essence(mimeType) !== essence) {
charset = null;
const newCharset = MapPrototypeGet(mimeType.parameters, "charset");
if (newCharset !== undefined) {
charset = newCharset;
}
essence = mimesniff.essence(mimeType);
} else {
if (
MapPrototypeHas(mimeType.parameters, "charset") === null &&
charset !== null
) {
MapPrototypeSet(mimeType.parameters, "charset", charset);
}
}
}
if (mimeType === null) return null;
return mimeType;
return extractMimeType(values);
}
get [_body]() {
return this[_response].body;

View file

@ -12,6 +12,7 @@
const {
ArrayPrototypeIncludes,
Map,
MapPrototypeGet,
MapPrototypeHas,
MapPrototypeSet,
RegExpPrototypeTest,
@ -207,5 +208,51 @@
return serialization;
}
window.__bootstrap.mimesniff = { parseMimeType, essence, serializeMimeType };
/**
* Part of the Fetch spec's "extract a MIME type" algorithm
* (https://fetch.spec.whatwg.org/#concept-header-extract-mime-type).
* @param {string[] | null} headerValues The result of getting, decoding and
* splitting the "Content-Type" header.
* @returns {MimeType | null}
*/
function extractMimeType(headerValues) {
if (headerValues === null) return null;
let charset = null;
let essence_ = null;
let mimeType = null;
for (const value of headerValues) {
const temporaryMimeType = parseMimeType(value);
if (
temporaryMimeType === null ||
essence(temporaryMimeType) == "*/*"
) {
continue;
}
mimeType = temporaryMimeType;
if (essence(mimeType) !== essence_) {
charset = null;
const newCharset = MapPrototypeGet(mimeType.parameters, "charset");
if (newCharset !== undefined) {
charset = newCharset;
}
essence_ = essence(mimeType);
} else {
if (
!MapPrototypeHas(mimeType.parameters, "charset") &&
charset !== null
) {
MapPrototypeSet(mimeType.parameters, "charset", charset);
}
}
}
return mimeType;
}
window.__bootstrap.mimesniff = {
parseMimeType,
essence,
serializeMimeType,
extractMimeType,
};
})(this);

View file

@ -60,6 +60,9 @@ declare namespace globalThis {
declare function parseMimeType(input: string): MimeType | null;
declare function essence(mimeType: MimeType): string;
declare function serializeMimeType(mimeType: MimeType): string;
declare function extractMimeType(
headerValues: string[] | null,
): MimeType | null;
}
declare var eventTarget: {