forked from oakserver/oak
-
Notifications
You must be signed in to change notification settings - Fork 0
/
isMediaType.ts
93 lines (75 loc) · 2.09 KB
/
isMediaType.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*!
* Adapted directly from type-is at https://github.com/jshttp/type-is/
* which is licensed as follows:
*
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
import { lookup } from "./deps.ts";
import { parse, format } from "./mediaTyper.ts";
function mimeMatch(expected: string | undefined, actual: string): boolean {
if (expected === undefined) {
return false;
}
const actualParts = actual.split("/");
const expectedParts = expected.split("/");
if (actualParts.length !== 2 || expectedParts.length !== 2) {
return false;
}
const [actualType, actualSubtype] = actualParts;
const [expectedType, expectedSubtype] = expectedParts;
if (expectedType !== "*" && expectedType !== actualType) {
return false;
}
if (expectedSubtype.substr(0, 2) === "*+") {
return (
expectedSubtype.length <= actualSubtype.length + 1 &&
expectedSubtype.substr(1) ===
actualSubtype.substr(1 - expectedSubtype.length)
);
}
if (expectedSubtype !== "*" && expectedSubtype !== actualSubtype) {
return false;
}
return true;
}
function normalize(type: string): string | undefined {
switch (type) {
case "urlencoded":
return "application/x-www-form-urlencoded";
case "multipart":
return "multipart/*";
}
if (type[0] === "+") {
return `*/*${type}`;
}
return type.includes("/") ? type : lookup(type);
}
function normalizeType(value: string): string | undefined {
try {
const val = value.split(";");
const type = parse(val[0]);
return format(type);
} catch {
return;
}
}
/** Given a value of the content type of a request and an array of types,
* provide the matching type or `false` if no types are matched.
*/
export function isMediaType(value: string, types: string[]): string | false {
const val = normalizeType(value);
if (!val) {
return false;
}
if (!types.length) {
return val;
}
for (const type of types) {
if (mimeMatch(normalize(type), val)) {
return type[0] === "+" || type.includes("*") ? val : type;
}
}
return false;
}