xref: /aosp_15_r20/external/cronet/net/base/mime_util_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/base/mime_util.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <vector>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
12*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
13*6777b538SAndroid Build Coastguard Worker #include "build/chromeos_buildflags.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
15*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace net {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker using testing::Contains;
20*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,GetWellKnownMimeTypeFromExtension)21*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, GetWellKnownMimeTypeFromExtension) {
22*6777b538SAndroid Build Coastguard Worker   // String: png\0css
23*6777b538SAndroid Build Coastguard Worker   base::FilePath::StringType containsNullByte;
24*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(FILE_PATH_LITERAL("png"));
25*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(1, FILE_PATH_LITERAL('\0'));
26*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(FILE_PATH_LITERAL("css"));
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker   const struct {
29*6777b538SAndroid Build Coastguard Worker     const base::FilePath::StringType extension;
30*6777b538SAndroid Build Coastguard Worker     const char* const mime_type;
31*6777b538SAndroid Build Coastguard Worker   } tests[] = {
32*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("png"), "image/png"},
33*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("PNG"), "image/png"},
34*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("css"), "text/css"},
35*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("pjp"), "image/jpeg"},
36*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("pjpeg"), "image/jpeg"},
37*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("json"), "application/json"},
38*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("js"), "text/javascript"},
39*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("webm"), "video/webm"},
40*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("weba"), "audio/webm"},
41*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("avif"), "image/avif"},
42*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("epub"), "application/epub+zip"},
43*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("apk"), "application/vnd.android.package-archive"},
44*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("cer"), "application/x-x509-ca-cert"},
45*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("crt"), "application/x-x509-ca-cert"},
46*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("zip"), "application/zip"},
47*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("ics"), "text/calendar"},
48*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("m3u8"), "application/x-mpegurl"},
49*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("csv"), "text/csv"},
50*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("not an extension / for sure"), nullptr},
51*6777b538SAndroid Build Coastguard Worker       {containsNullByte, nullptr}};
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
54*6777b538SAndroid Build Coastguard Worker     std::string mime_type;
55*6777b538SAndroid Build Coastguard Worker     if (GetWellKnownMimeTypeFromExtension(test.extension, &mime_type))
56*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test.mime_type, mime_type);
57*6777b538SAndroid Build Coastguard Worker     else
58*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test.mime_type, nullptr);
59*6777b538SAndroid Build Coastguard Worker   }
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,ExtensionTest)62*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, ExtensionTest) {
63*6777b538SAndroid Build Coastguard Worker   // String: png\0css
64*6777b538SAndroid Build Coastguard Worker   base::FilePath::StringType containsNullByte;
65*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(FILE_PATH_LITERAL("png"));
66*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(1, FILE_PATH_LITERAL('\0'));
67*6777b538SAndroid Build Coastguard Worker   containsNullByte.append(FILE_PATH_LITERAL("css"));
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker   const struct {
70*6777b538SAndroid Build Coastguard Worker     const base::FilePath::StringType extension;
71*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string> mime_types;
72*6777b538SAndroid Build Coastguard Worker   } tests[] = {
73*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("png"), {"image/png"}},
74*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("PNG"), {"image/png"}},
75*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("css"), {"text/css"}},
76*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("pjp"), {"image/jpeg"}},
77*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("pjpeg"), {"image/jpeg"}},
78*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("json"), {"application/json"}},
79*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("js"), {"text/javascript"}},
80*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("webm"), {"video/webm"}},
81*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("weba"), {"audio/webm"}},
82*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("avif"), {"image/avif"}},
83*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH)
84*6777b538SAndroid Build Coastguard Worker     // These are test cases for testing platform mime types on ChromeOS.
85*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("epub"), {"application/epub+zip"}},
86*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("apk"), {"application/vnd.android.package-archive"}},
87*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("cer"),
88*6777b538SAndroid Build Coastguard Worker      {
89*6777b538SAndroid Build Coastguard Worker          "application/x-x509-ca-cert",
90*6777b538SAndroid Build Coastguard Worker          "application/pkix-cert",  // System override for ChromeOS.
91*6777b538SAndroid Build Coastguard Worker      }},
92*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("crt"),
93*6777b538SAndroid Build Coastguard Worker      {
94*6777b538SAndroid Build Coastguard Worker          "application/x-x509-ca-cert",
95*6777b538SAndroid Build Coastguard Worker          "application/pkix-cert",  // System override for ChromeOS.
96*6777b538SAndroid Build Coastguard Worker      }},
97*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("zip"), {"application/zip"}},
98*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("ics"), {"text/calendar"}},
99*6777b538SAndroid Build Coastguard Worker #endif
100*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("m3u8"),
101*6777b538SAndroid Build Coastguard Worker      {
102*6777b538SAndroid Build Coastguard Worker          "application/x-mpegurl",  // Chrome's secondary mapping.
103*6777b538SAndroid Build Coastguard Worker          "audio/x-mpegurl",  // https://crbug.com/1273061, system override for
104*6777b538SAndroid Build Coastguard Worker                              // android-arm[64]-test and Linux. Possibly more.
105*6777b538SAndroid Build Coastguard Worker          "audio/mpegurl",                  // System override for mac.
106*6777b538SAndroid Build Coastguard Worker      }},
107*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("csv"), {"text/csv"}},
108*6777b538SAndroid Build Coastguard Worker     {FILE_PATH_LITERAL("not an extension / for sure"), {}},
109*6777b538SAndroid Build Coastguard Worker     {containsNullByte, {}}
110*6777b538SAndroid Build Coastguard Worker   };
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
113*6777b538SAndroid Build Coastguard Worker     std::string mime_type;
114*6777b538SAndroid Build Coastguard Worker     if (GetMimeTypeFromExtension(test.extension, &mime_type))
115*6777b538SAndroid Build Coastguard Worker       EXPECT_THAT(test.mime_types, Contains(mime_type));
116*6777b538SAndroid Build Coastguard Worker     else
117*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(test.mime_types.empty());
118*6777b538SAndroid Build Coastguard Worker   }
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker // Behavior of GetPreferredExtensionForMimeType() is dependent on the host
122*6777b538SAndroid Build Coastguard Worker // platform since the latter can override the mapping from file extensions to
123*6777b538SAndroid Build Coastguard Worker // MIME types. The tests below would only work if the platform MIME mappings
124*6777b538SAndroid Build Coastguard Worker // don't have mappings for or has an agreeing mapping for each MIME type
125*6777b538SAndroid Build Coastguard Worker // mentioned.
TEST(MimeUtilTest,GetPreferredExtensionForMimeType)126*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, GetPreferredExtensionForMimeType) {
127*6777b538SAndroid Build Coastguard Worker   const struct {
128*6777b538SAndroid Build Coastguard Worker     const std::string mime_type;
129*6777b538SAndroid Build Coastguard Worker     const base::FilePath::StringType expected_extension;
130*6777b538SAndroid Build Coastguard Worker   } kTestCases[] = {
131*6777b538SAndroid Build Coastguard Worker       {"application/wasm", FILE_PATH_LITERAL("wasm")},      // Primary
132*6777b538SAndroid Build Coastguard Worker       {"application/javascript", FILE_PATH_LITERAL("js")},  // Secondary
133*6777b538SAndroid Build Coastguard Worker       {"text/javascript", FILE_PATH_LITERAL("js")},         // Primary
134*6777b538SAndroid Build Coastguard Worker       {"video/webm", FILE_PATH_LITERAL("webm")},            // Primary
135*6777b538SAndroid Build Coastguard Worker   };
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   for (const auto& test : kTestCases) {
138*6777b538SAndroid Build Coastguard Worker     base::FilePath::StringType extension;
139*6777b538SAndroid Build Coastguard Worker     auto rv = GetPreferredExtensionForMimeType(test.mime_type, &extension);
140*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(rv);
141*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.expected_extension, extension);
142*6777b538SAndroid Build Coastguard Worker   }
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,FileTest)145*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, FileTest) {
146*6777b538SAndroid Build Coastguard Worker   const struct {
147*6777b538SAndroid Build Coastguard Worker     const base::FilePath::CharType* file_path;
148*6777b538SAndroid Build Coastguard Worker     const char* const mime_type;
149*6777b538SAndroid Build Coastguard Worker     bool valid;
150*6777b538SAndroid Build Coastguard Worker   } tests[] = {
151*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("c:\\foo\\bar.css"), "text/css", true},
152*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("c:\\foo\\bar.CSS"), "text/css", true},
153*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("c:\\blah"), "", false},
154*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("/usr/local/bin/mplayer"), "", false},
155*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("/home/foo/bar.css"), "text/css", true},
156*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("/blah."), "", false},
157*6777b538SAndroid Build Coastguard Worker       {FILE_PATH_LITERAL("c:\\blah."), "", false},
158*6777b538SAndroid Build Coastguard Worker   };
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   std::string mime_type;
161*6777b538SAndroid Build Coastguard Worker   bool rv;
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
164*6777b538SAndroid Build Coastguard Worker     rv = GetMimeTypeFromFile(base::FilePath(test.file_path), &mime_type);
165*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.valid, rv);
166*6777b538SAndroid Build Coastguard Worker     if (rv)
167*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test.mime_type, mime_type);
168*6777b538SAndroid Build Coastguard Worker   }
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,MatchesMimeType)171*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, MatchesMimeType) {
172*6777b538SAndroid Build Coastguard Worker   // MIME types are case insensitive.
173*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("VIDEO/*", "video/x-mpeg"));
174*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*", "VIDEO/X-MPEG"));
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", "video/x-mpeg"));
177*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*", "video/x-mpeg"));
178*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*", "video/*"));
179*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg", "video/x-mpeg"));
180*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("application/*+xml",
181*6777b538SAndroid Build Coastguard Worker                                    "application/html+xml"));
182*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("application/*+xml", "application/+xml"));
183*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("application/*+json",
184*6777b538SAndroid Build Coastguard Worker                                    "application/x-myformat+json"));
185*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("aaa*aaa", "aaaaaa"));
186*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", std::string()));
187*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/", "video/x-mpeg"));
188*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("VIDEO/", "Video/X-MPEG"));
189*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType(std::string(), "video/x-mpeg"));
190*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType(std::string(), std::string()));
191*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/x-mpeg", std::string()));
192*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("application/*+xml", "application/xml"));
193*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("application/*+xml",
194*6777b538SAndroid Build Coastguard Worker                                     "application/html+xmlz"));
195*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("application/*+xml",
196*6777b538SAndroid Build Coastguard Worker                                     "applcation/html+xml"));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("aaa*aaa", "aaaaa"));
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", "video/x-mpeg;param=val"));
200*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", "Video/X-MPEG;PARAM=VAL"));
201*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*", "video/x-mpeg;param=val"));
202*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/mpeg"));
203*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("Video/*;PARAM=VAL", "VIDEO/Mpeg"));
204*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/mpeg;param=other"));
205*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*;param=val", "video/mpeg;param=val"));
206*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("Video/*;PARAM=Val", "VIDEO/Mpeg;Param=Val"));
207*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("Video/*;PARAM=VAL", "VIDEO/Mpeg;Param=Val"));
208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg", "video/x-mpeg;param=val"));
209*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val",
210*6777b538SAndroid Build Coastguard Worker                               "video/x-mpeg;param=val"));
211*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param2=val2",
212*6777b538SAndroid Build Coastguard Worker                                "video/x-mpeg;param=val"));
213*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param2=val2",
214*6777b538SAndroid Build Coastguard Worker                                "video/x-mpeg;param2=val"));
215*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val",
216*6777b538SAndroid Build Coastguard Worker                               "video/x-mpeg;param=val;param2=val2"));
217*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("Video/X-Mpeg;Param=Val",
218*6777b538SAndroid Build Coastguard Worker                               "VIDEO/X-MPEG;PARAM=Val;PARAM2=val2"));
219*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("Video/X-Mpeg;Param=VAL",
220*6777b538SAndroid Build Coastguard Worker                               "VIDEO/X-MPEG;PARAM=VAL;PARAM2=val2"));
221*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("Video/X-Mpeg;Param=val",
222*6777b538SAndroid Build Coastguard Worker                                "VIDEO/X-MPEG;PARAM=VAL;PARAM2=val2"));
223*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param=VAL;param2=val2",
224*6777b538SAndroid Build Coastguard Worker                                "video/x-mpeg;param=val;param2=val2"));
225*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param2=val2;param=val",
226*6777b538SAndroid Build Coastguard Worker                               "video/x-mpeg;param=val;param2=val2"));
227*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param3=val3;param=val",
228*6777b538SAndroid Build Coastguard Worker                                "video/x-mpeg;param=val;param2=val2"));
229*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val ;param2=val2 ",
230*6777b538SAndroid Build Coastguard Worker                               "video/x-mpeg;param=val;param2=val2"));
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*/*;param=val", "video/x-mpeg;param=val"));
233*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("*/*;param=val", "video/x-mpeg;param=val2"));
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", "*"));
236*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*", "*/*"));
237*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*/*", "*/*"));
238*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("*/*", "*"));
239*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*", "video/*"));
240*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/*", "*/*"));
241*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/*"));
242*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("video/*;param=val", "video/*;param=val"));
243*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/*;param=val2"));
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("ab*cd", "abxxxcd"));
246*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("ab*cd", "abx/xcd"));
247*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MatchesMimeType("ab/*cd", "ab/xxxcd"));
248*6777b538SAndroid Build Coastguard Worker }
249*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestParseMimeType)250*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestParseMimeType) {
251*6777b538SAndroid Build Coastguard Worker   const struct {
252*6777b538SAndroid Build Coastguard Worker     std::string type_str;
253*6777b538SAndroid Build Coastguard Worker     std::string mime_type;
254*6777b538SAndroid Build Coastguard Worker     base::StringPairs params;
255*6777b538SAndroid Build Coastguard Worker   } tests[] = {
256*6777b538SAndroid Build Coastguard Worker       // Simple tests.
257*6777b538SAndroid Build Coastguard Worker       {"image/jpeg", "image/jpeg"},
258*6777b538SAndroid Build Coastguard Worker       {"application/octet-stream;foo=bar;name=\"test.jpg\"",
259*6777b538SAndroid Build Coastguard Worker        "application/octet-stream",
260*6777b538SAndroid Build Coastguard Worker        {{"foo", "bar"}, {"name", "test.jpg"}}},
261*6777b538SAndroid Build Coastguard Worker       // Quoted string parsing.
262*6777b538SAndroid Build Coastguard Worker       {"t/s;name=\"t\\\\est\\\".jpg\"", "t/s", {{"name", "t\\est\".jpg"}}},
263*6777b538SAndroid Build Coastguard Worker       {"t/s;name=\"test.jpg\"", "t/s", {{"name", "test.jpg"}}},
264*6777b538SAndroid Build Coastguard Worker       {"t/s;name=\"test;jpg\"", "t/s", {{"name", "test;jpg"}}},
265*6777b538SAndroid Build Coastguard Worker       // Lenient for no closing quote.
266*6777b538SAndroid Build Coastguard Worker       {"t/s;name=\"test.jpg", "t/s", {{"name", "test.jpg"}}},
267*6777b538SAndroid Build Coastguard Worker       {"t/s;name=\"ab\\\"", "t/s", {{"name", "ab\""}}},
268*6777b538SAndroid Build Coastguard Worker       // Strip whitespace from start/end of mime_type.
269*6777b538SAndroid Build Coastguard Worker       {" t/s", "t/s"},
270*6777b538SAndroid Build Coastguard Worker       {"t/s ", "t/s"},
271*6777b538SAndroid Build Coastguard Worker       {" t/s ", "t/s"},
272*6777b538SAndroid Build Coastguard Worker       {"t/=", "t/="},
273*6777b538SAndroid Build Coastguard Worker       // Generally ignore whitespace.
274*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1;b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
275*6777b538SAndroid Build Coastguard Worker       {"t/s ;a=1;b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
276*6777b538SAndroid Build Coastguard Worker       {"t/s; a=1;b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
277*6777b538SAndroid Build Coastguard Worker       // Special case, include whitespace after param name until equals.
278*6777b538SAndroid Build Coastguard Worker       {"t/s;a =1;b=2", "t/s", {{"a ", "1"}, {"b", "2"}}},
279*6777b538SAndroid Build Coastguard Worker       {"t/s;a= 1;b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
280*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1 ;b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
281*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1; b=2", "t/s", {{"a", "1"}, {"b", "2"}}},
282*6777b538SAndroid Build Coastguard Worker       {"t/s; a = 1;b=2", "t/s", {{"a ", "1"}, {"b", "2"}}},
283*6777b538SAndroid Build Coastguard Worker       // Do not trim whitespace from quoted-string param values.
284*6777b538SAndroid Build Coastguard Worker       {"t/s;a=\" 1\";b=2", "t/s", {{"a", " 1"}, {"b", "2"}}},
285*6777b538SAndroid Build Coastguard Worker       {"t/s;a=\"1 \";b=2", "t/s", {{"a", "1 "}, {"b", "2"}}},
286*6777b538SAndroid Build Coastguard Worker       {"t/s;a=\" 1 \";b=2", "t/s", {{"a", " 1 "}, {"b", "2"}}},
287*6777b538SAndroid Build Coastguard Worker       // Ignore incomplete params.
288*6777b538SAndroid Build Coastguard Worker       {"t/s;a", "t/s", {}},
289*6777b538SAndroid Build Coastguard Worker       {"t/s;a=", "t/s", {}},
290*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1;", "t/s", {{"a", "1"}}},
291*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1;b", "t/s", {{"a", "1"}}},
292*6777b538SAndroid Build Coastguard Worker       {"t/s;a=1;b=", "t/s", {{"a", "1"}}},
293*6777b538SAndroid Build Coastguard Worker       // Allow empty subtype.
294*6777b538SAndroid Build Coastguard Worker       {"t/", "t/", {}},
295*6777b538SAndroid Build Coastguard Worker       {"ts/", "ts/", {}},
296*6777b538SAndroid Build Coastguard Worker       {"t/;", "t/", {}},
297*6777b538SAndroid Build Coastguard Worker       {"t/ s", "t/", {}},
298*6777b538SAndroid Build Coastguard Worker       // Questionable: allow anything as long as there is a slash somewhere.
299*6777b538SAndroid Build Coastguard Worker       {"/ts", "/ts", {}},
300*6777b538SAndroid Build Coastguard Worker       {"/s", "/s", {}},
301*6777b538SAndroid Build Coastguard Worker       {"/", "/", {}},
302*6777b538SAndroid Build Coastguard Worker   };
303*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
304*6777b538SAndroid Build Coastguard Worker     std::string mime_type;
305*6777b538SAndroid Build Coastguard Worker     base::StringPairs params;
306*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(ParseMimeType(test.type_str, &mime_type, &params));
307*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.mime_type, mime_type);
308*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.params, params);
309*6777b538SAndroid Build Coastguard Worker   }
310*6777b538SAndroid Build Coastguard Worker   for (auto* type_str : {
311*6777b538SAndroid Build Coastguard Worker            // Must have slash in mime type.
312*6777b538SAndroid Build Coastguard Worker            "",
313*6777b538SAndroid Build Coastguard Worker            "ts",
314*6777b538SAndroid Build Coastguard Worker            "t / s",
315*6777b538SAndroid Build Coastguard Worker        }) {
316*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(ParseMimeType(type_str, nullptr, nullptr));
317*6777b538SAndroid Build Coastguard Worker   }
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestParseMimeTypeWithoutParameter)320*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestParseMimeTypeWithoutParameter) {
321*6777b538SAndroid Build Coastguard Worker   std::string nonAscii("application/nonutf8");
322*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter(nonAscii, nullptr, nullptr));
323*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
324*6777b538SAndroid Build Coastguard Worker   nonAscii.append(base::WideToUTF8(L"\u2603"));
325*6777b538SAndroid Build Coastguard Worker #else
326*6777b538SAndroid Build Coastguard Worker   nonAscii.append("\u2603");  // unicode snowman
327*6777b538SAndroid Build Coastguard Worker #endif
328*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter(nonAscii, nullptr, nullptr));
329*6777b538SAndroid Build Coastguard Worker 
330*6777b538SAndroid Build Coastguard Worker   std::string top_level_type;
331*6777b538SAndroid Build Coastguard Worker   std::string subtype;
332*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter(
333*6777b538SAndroid Build Coastguard Worker       "application/mime", &top_level_type, &subtype));
334*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("application", top_level_type);
335*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("mime", subtype);
336*6777b538SAndroid Build Coastguard Worker 
337*6777b538SAndroid Build Coastguard Worker   // Various allowed subtype forms.
338*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
339*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("application/json", nullptr, nullptr));
340*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("application/x-suggestions+json",
341*6777b538SAndroid Build Coastguard Worker                                             nullptr, nullptr));
342*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
343*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("application/+json", nullptr, nullptr));
344*6777b538SAndroid Build Coastguard Worker 
345*6777b538SAndroid Build Coastguard Worker   // Upper case letters are allowed.
346*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/mime", nullptr, nullptr));
347*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("TEXT/mime", nullptr, nullptr));
348*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("Text/mime", nullptr, nullptr));
349*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("TeXt/mime", nullptr, nullptr));
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   // Experimental types are also considered to be valid.
352*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("x-video/mime", nullptr, nullptr));
353*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("X-Video/mime", nullptr, nullptr));
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text", nullptr, nullptr));
356*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/", nullptr, nullptr));
357*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/ ", nullptr, nullptr));
358*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("te(xt/ ", nullptr, nullptr));
359*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/()plain", nullptr, nullptr));
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("x-video", nullptr, nullptr));
362*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("x-video/", nullptr, nullptr));
363*6777b538SAndroid Build Coastguard Worker 
364*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
365*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("application/a/b/c", nullptr, nullptr));
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker   // Test leading and trailing whitespace
368*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter(" text/plain", nullptr, nullptr));
369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain ", nullptr, nullptr));
370*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text /plain", nullptr, nullptr));
371*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/ plain ", nullptr, nullptr));
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ttext/plain", nullptr, nullptr));
374*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\t", nullptr, nullptr));
375*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\t/plain", nullptr, nullptr));
376*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
377*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("text/\tplain ", nullptr, nullptr));
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("\vtext/plain", nullptr, nullptr));
380*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\v", nullptr, nullptr));
381*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\v/plain", nullptr, nullptr));
382*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
383*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("text/\vplain ", nullptr, nullptr));
384*6777b538SAndroid Build Coastguard Worker 
385*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("\rtext/plain", nullptr, nullptr));
386*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\r", nullptr, nullptr));
387*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\r/plain", nullptr, nullptr));
388*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
389*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("text/\rplain ", nullptr, nullptr));
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ntext/plain", nullptr, nullptr));
392*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\n", nullptr, nullptr));
393*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\n/plain", nullptr, nullptr));
394*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
395*6777b538SAndroid Build Coastguard Worker       ParseMimeTypeWithoutParameter("text/\nplain ", nullptr, nullptr));
396*6777b538SAndroid Build Coastguard Worker }
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker class ExtractMIMETypeTestInvalid : public testing::TestWithParam<std::string> {
399*6777b538SAndroid Build Coastguard Worker };
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
402*6777b538SAndroid Build Coastguard Worker     InvalidMediaTypes,
403*6777b538SAndroid Build Coastguard Worker     ExtractMIMETypeTestInvalid,
404*6777b538SAndroid Build Coastguard Worker     testing::Values(
405*6777b538SAndroid Build Coastguard Worker         // Fails because it doesn't contain '/'.
406*6777b538SAndroid Build Coastguard Worker         "a",
407*6777b538SAndroid Build Coastguard Worker         "application",
408*6777b538SAndroid Build Coastguard Worker         // Space is not HTTP token code point.
409*6777b538SAndroid Build Coastguard Worker         //  https://mimesniff.spec.whatwg.org/#http-token-code-point
410*6777b538SAndroid Build Coastguard Worker         // U+2003, EM SPACE (UTF-8: E2 80 83).
411*6777b538SAndroid Build Coastguard Worker         "\xE2\x80\x83text/html",
412*6777b538SAndroid Build Coastguard Worker         "text\xE2\x80\x83/html",
413*6777b538SAndroid Build Coastguard Worker         "text / html",
414*6777b538SAndroid Build Coastguard Worker         "t e x t / h t m l",
415*6777b538SAndroid Build Coastguard Worker         "text\r\n/\nhtml",
416*6777b538SAndroid Build Coastguard Worker         "text\n/\nhtml",
417*6777b538SAndroid Build Coastguard Worker         ", text/html",
418*6777b538SAndroid Build Coastguard Worker         "; text/html"));
419*6777b538SAndroid Build Coastguard Worker 
TEST_P(ExtractMIMETypeTestInvalid,MustFail)420*6777b538SAndroid Build Coastguard Worker TEST_P(ExtractMIMETypeTestInvalid, MustFail) {
421*6777b538SAndroid Build Coastguard Worker   // Parsing is expected to fail.
422*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, net::ExtractMimeTypeFromMediaType(GetParam(), true));
423*6777b538SAndroid Build Coastguard Worker }
424*6777b538SAndroid Build Coastguard Worker 
425*6777b538SAndroid Build Coastguard Worker class ExtractMIMETypeTestValid : public testing::TestWithParam<std::string> {};
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
428*6777b538SAndroid Build Coastguard Worker     ValidMediaTypes,
429*6777b538SAndroid Build Coastguard Worker     ExtractMIMETypeTestValid,
430*6777b538SAndroid Build Coastguard Worker     testing::Values("text/html",
431*6777b538SAndroid Build Coastguard Worker                     "text/html; charset=iso-8859-1",
432*6777b538SAndroid Build Coastguard Worker                     // Quoted charset parameter.
433*6777b538SAndroid Build Coastguard Worker                     "text/html; charset=\"quoted\"",
434*6777b538SAndroid Build Coastguard Worker                     // Multiple parameters.
435*6777b538SAndroid Build Coastguard Worker                     "text/html; charset=x; foo=bar",
436*6777b538SAndroid Build Coastguard Worker                     // OWSes are trimmed.
437*6777b538SAndroid Build Coastguard Worker                     " text/html   ",
438*6777b538SAndroid Build Coastguard Worker                     "\ttext/html \t",
439*6777b538SAndroid Build Coastguard Worker                     "text/html ; charset=iso-8859-1"
440*6777b538SAndroid Build Coastguard Worker                     // Non-standard multiple type/subtype listing using a comma
441*6777b538SAndroid Build Coastguard Worker                     // as a separator is accepted.
442*6777b538SAndroid Build Coastguard Worker                     "text/html,text/plain",
443*6777b538SAndroid Build Coastguard Worker                     "text/html , text/plain",
444*6777b538SAndroid Build Coastguard Worker                     "text/html\t,\ttext/plain",
445*6777b538SAndroid Build Coastguard Worker                     "text/html,text/plain;charset=iso-8859-1",
446*6777b538SAndroid Build Coastguard Worker                     "\r\ntext/html\r\n",
447*6777b538SAndroid Build Coastguard Worker                     "text/html;wow",
448*6777b538SAndroid Build Coastguard Worker                     "text/html;;;;;;",
449*6777b538SAndroid Build Coastguard Worker                     "text/html; = = = "));
450*6777b538SAndroid Build Coastguard Worker 
TEST_P(ExtractMIMETypeTestValid,MustSucceed)451*6777b538SAndroid Build Coastguard Worker TEST_P(ExtractMIMETypeTestValid, MustSucceed) {
452*6777b538SAndroid Build Coastguard Worker   //  net::ExtractMIMETypeFromMediaType parses well-formed headers correctly.
453*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("text/html",
454*6777b538SAndroid Build Coastguard Worker             net::ExtractMimeTypeFromMediaType(GetParam(), true).value_or(""));
455*6777b538SAndroid Build Coastguard Worker }
456*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestIsValidTopLevelMimeType)457*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestIsValidTopLevelMimeType) {
458*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("application"));
459*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("audio"));
460*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("example"));
461*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("font"));
462*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("image"));
463*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("message"));
464*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("model"));
465*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("multipart"));
466*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("text"));
467*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("video"));
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("TEXT"));
470*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("Text"));
471*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("TeXt"));
472*6777b538SAndroid Build Coastguard Worker 
473*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsValidTopLevelMimeType("mime"));
474*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsValidTopLevelMimeType(""));
475*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsValidTopLevelMimeType("/"));
476*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsValidTopLevelMimeType(" "));
477*6777b538SAndroid Build Coastguard Worker 
478*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("x-video"));
479*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsValidTopLevelMimeType("X-video"));
480*6777b538SAndroid Build Coastguard Worker 
481*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsValidTopLevelMimeType("x-"));
482*6777b538SAndroid Build Coastguard Worker }
483*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestGetExtensionsForMimeType)484*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestGetExtensionsForMimeType) {
485*6777b538SAndroid Build Coastguard Worker   const struct {
486*6777b538SAndroid Build Coastguard Worker     const char* const mime_type;
487*6777b538SAndroid Build Coastguard Worker     size_t min_expected_size;
488*6777b538SAndroid Build Coastguard Worker     const char* const contained_result;
489*6777b538SAndroid Build Coastguard Worker     bool no_matches;
490*6777b538SAndroid Build Coastguard Worker   } tests[] = {
491*6777b538SAndroid Build Coastguard Worker       {"text/plain", 2, "txt"},
492*6777b538SAndroid Build Coastguard Worker       {"text/pl", 0, nullptr, true},
493*6777b538SAndroid Build Coastguard Worker       {"*", 0, nullptr},
494*6777b538SAndroid Build Coastguard Worker       {"", 0, nullptr, true},
495*6777b538SAndroid Build Coastguard Worker       {"message/*", 1, "eml"},
496*6777b538SAndroid Build Coastguard Worker       {"MeSsAge/*", 1, "eml"},
497*6777b538SAndroid Build Coastguard Worker       {"message/", 0, nullptr, true},
498*6777b538SAndroid Build Coastguard Worker       {"image/avif", 1, "avif"},
499*6777b538SAndroid Build Coastguard Worker       {"image/bmp", 1, "bmp"},
500*6777b538SAndroid Build Coastguard Worker       {"video/*", 6, "mp4"},
501*6777b538SAndroid Build Coastguard Worker       {"video/*", 6, "mpeg"},
502*6777b538SAndroid Build Coastguard Worker       {"audio/*", 6, "oga"},
503*6777b538SAndroid Build Coastguard Worker       {"aUDIo/*", 6, "wav"},
504*6777b538SAndroid Build Coastguard Worker   };
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
507*6777b538SAndroid Build Coastguard Worker     std::vector<base::FilePath::StringType> extensions;
508*6777b538SAndroid Build Coastguard Worker     GetExtensionsForMimeType(test.mime_type, &extensions);
509*6777b538SAndroid Build Coastguard Worker     ASSERT_LE(test.min_expected_size, extensions.size());
510*6777b538SAndroid Build Coastguard Worker 
511*6777b538SAndroid Build Coastguard Worker     if (test.no_matches)
512*6777b538SAndroid Build Coastguard Worker       ASSERT_EQ(0u, extensions.size());
513*6777b538SAndroid Build Coastguard Worker 
514*6777b538SAndroid Build Coastguard Worker     if (test.contained_result) {
515*6777b538SAndroid Build Coastguard Worker       // Convert ASCII to FilePath::StringType.
516*6777b538SAndroid Build Coastguard Worker       base::FilePath::StringType contained_result(
517*6777b538SAndroid Build Coastguard Worker           test.contained_result,
518*6777b538SAndroid Build Coastguard Worker           test.contained_result + strlen(test.contained_result));
519*6777b538SAndroid Build Coastguard Worker 
520*6777b538SAndroid Build Coastguard Worker       bool found = base::Contains(extensions, contained_result);
521*6777b538SAndroid Build Coastguard Worker 
522*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(found) << "Must find at least the contained result within "
523*6777b538SAndroid Build Coastguard Worker                          << test.mime_type;
524*6777b538SAndroid Build Coastguard Worker     }
525*6777b538SAndroid Build Coastguard Worker   }
526*6777b538SAndroid Build Coastguard Worker }
527*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestGenerateMimeMultipartBoundary)528*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestGenerateMimeMultipartBoundary) {
529*6777b538SAndroid Build Coastguard Worker   std::string boundary1 = GenerateMimeMultipartBoundary();
530*6777b538SAndroid Build Coastguard Worker   std::string boundary2 = GenerateMimeMultipartBoundary();
531*6777b538SAndroid Build Coastguard Worker 
532*6777b538SAndroid Build Coastguard Worker   // RFC 1341 says: the boundary parameter [...] consists of 1 to 70 characters.
533*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(70u, boundary1.size());
534*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(70u, boundary2.size());
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker   // RFC 1341 asks to: exercise care to choose a unique boundary.
537*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(boundary1, boundary2);
538*6777b538SAndroid Build Coastguard Worker   ASSERT_LE(16u, boundary1.size());
539*6777b538SAndroid Build Coastguard Worker   ASSERT_LE(16u, boundary2.size());
540*6777b538SAndroid Build Coastguard Worker 
541*6777b538SAndroid Build Coastguard Worker   // Expect that we don't pick '\0' character from the array/string
542*6777b538SAndroid Build Coastguard Worker   // where we take the characters from.
543*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, boundary1.find('\0'));
544*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, boundary2.find('\0'));
545*6777b538SAndroid Build Coastguard Worker 
546*6777b538SAndroid Build Coastguard Worker   // Asserts below are not RFC 1341 requirements, but are here
547*6777b538SAndroid Build Coastguard Worker   // to improve readability of generated MIME documents and to
548*6777b538SAndroid Build Coastguard Worker   // try to preserve some aspects of the old boundary generation code.
549*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("--", boundary1.substr(0, 2));
550*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("--", boundary2.substr(0, 2));
551*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, boundary1.find("MultipartBoundary"));
552*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, boundary2.find("MultipartBoundary"));
553*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("--", boundary1.substr(boundary1.size() - 2, 2));
554*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("--", boundary2.substr(boundary2.size() - 2, 2));
555*6777b538SAndroid Build Coastguard Worker }
556*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestAddMultipartValueForUpload)557*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestAddMultipartValueForUpload) {
558*6777b538SAndroid Build Coastguard Worker   const char ref_output[] =
559*6777b538SAndroid Build Coastguard Worker       "--boundary\r\nContent-Disposition: form-data;"
560*6777b538SAndroid Build Coastguard Worker       " name=\"value name\"\r\nContent-Type: content type"
561*6777b538SAndroid Build Coastguard Worker       "\r\n\r\nvalue\r\n"
562*6777b538SAndroid Build Coastguard Worker       "--boundary\r\nContent-Disposition: form-data;"
563*6777b538SAndroid Build Coastguard Worker       " name=\"value name\"\r\n\r\nvalue\r\n"
564*6777b538SAndroid Build Coastguard Worker       "--boundary--\r\n";
565*6777b538SAndroid Build Coastguard Worker   std::string post_data;
566*6777b538SAndroid Build Coastguard Worker   AddMultipartValueForUpload("value name", "value", "boundary",
567*6777b538SAndroid Build Coastguard Worker                              "content type", &post_data);
568*6777b538SAndroid Build Coastguard Worker   AddMultipartValueForUpload("value name", "value", "boundary",
569*6777b538SAndroid Build Coastguard Worker                              "", &post_data);
570*6777b538SAndroid Build Coastguard Worker   AddMultipartFinalDelimiterForUpload("boundary", &post_data);
571*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(ref_output, post_data.c_str());
572*6777b538SAndroid Build Coastguard Worker }
573*6777b538SAndroid Build Coastguard Worker 
TEST(MimeUtilTest,TestAddMultipartValueForUploadWithFileName)574*6777b538SAndroid Build Coastguard Worker TEST(MimeUtilTest, TestAddMultipartValueForUploadWithFileName) {
575*6777b538SAndroid Build Coastguard Worker   const char ref_output[] =
576*6777b538SAndroid Build Coastguard Worker       "--boundary\r\nContent-Disposition: form-data;"
577*6777b538SAndroid Build Coastguard Worker       " name=\"value name\"; filename=\"file name\"\r\nContent-Type: content "
578*6777b538SAndroid Build Coastguard Worker       "type"
579*6777b538SAndroid Build Coastguard Worker       "\r\n\r\nvalue\r\n"
580*6777b538SAndroid Build Coastguard Worker       "--boundary\r\nContent-Disposition: form-data;"
581*6777b538SAndroid Build Coastguard Worker       " name=\"value name\"; filename=\"file name\"\r\n\r\nvalue\r\n"
582*6777b538SAndroid Build Coastguard Worker       "--boundary--\r\n";
583*6777b538SAndroid Build Coastguard Worker   std::string post_data;
584*6777b538SAndroid Build Coastguard Worker   AddMultipartValueForUploadWithFileName("value name", "file name", "value",
585*6777b538SAndroid Build Coastguard Worker                                          "boundary", "content type",
586*6777b538SAndroid Build Coastguard Worker                                          &post_data);
587*6777b538SAndroid Build Coastguard Worker   AddMultipartValueForUploadWithFileName("value name", "file name", "value",
588*6777b538SAndroid Build Coastguard Worker                                          "boundary", "", &post_data);
589*6777b538SAndroid Build Coastguard Worker   AddMultipartFinalDelimiterForUpload("boundary", &post_data);
590*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(ref_output, post_data.c_str());
591*6777b538SAndroid Build Coastguard Worker }
592*6777b538SAndroid Build Coastguard Worker }  // namespace net
593