OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "net/base/mime_util.h" | 8 #include "net/base/mime_util.h" |
9 #include "net/base/platform_mime_util.h" | 9 #include "net/base/platform_mime_util.h" |
10 | 10 |
11 #include "base/hash_tables.h" | 11 #include "base/hash_tables.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/singleton.h" | 13 #include "base/singleton.h" |
14 #include "base/string_split.h" | |
14 #include "base/string_util.h" | 15 #include "base/string_util.h" |
15 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
16 | 17 |
17 using std::string; | 18 using std::string; |
18 | 19 |
20 namespace { | |
darin (slow to review)
2010/09/08 05:18:32
it would have been OK to put the anonymous namespa
| |
21 | |
22 struct MimeInfo { | |
23 const char* mime_type; | |
24 const char* extensions; // comma separated list | |
25 }; | |
26 | |
27 static const MimeInfo kPrimaryMappings[] = { | |
28 { "text/html", "html,htm" }, | |
29 { "text/css", "css" }, | |
30 { "text/xml", "xml" }, | |
31 { "image/gif", "gif" }, | |
32 { "image/jpeg", "jpeg,jpg" }, | |
33 { "image/png", "png" }, | |
34 { "video/mp4", "mp4,m4v" }, | |
35 { "audio/x-m4a", "m4a" }, | |
36 { "audio/mp3", "mp3" }, | |
37 { "video/ogg", "ogv,ogm" }, | |
38 { "audio/ogg", "ogg,oga" }, | |
39 { "video/webm", "webm" }, | |
40 { "audio/webm", "webm" }, | |
41 { "application/xhtml+xml", "xhtml,xht" }, | |
42 { "application/x-chrome-extension", "crx" } | |
43 }; | |
44 | |
45 static const MimeInfo kSecondaryMappings[] = { | |
46 { "application/octet-stream", "exe,com,bin" }, | |
47 { "application/gzip", "gz" }, | |
48 { "application/pdf", "pdf" }, | |
49 { "application/postscript", "ps,eps,ai" }, | |
50 { "application/x-javascript", "js" }, | |
51 { "image/bmp", "bmp" }, | |
52 { "image/x-icon", "ico" }, | |
53 { "image/jpeg", "jfif,pjpeg,pjp" }, | |
54 { "image/tiff", "tiff,tif" }, | |
55 { "image/x-xbitmap", "xbm" }, | |
56 { "image/svg+xml", "svg,svgz" }, | |
57 { "message/rfc822", "eml" }, | |
58 { "text/plain", "txt,text" }, | |
59 { "text/html", "shtml,ehtml" }, | |
60 { "application/rss+xml", "rss" }, | |
61 { "application/rdf+xml", "rdf" }, | |
62 { "text/xml", "xsl,xbl" }, | |
63 { "application/vnd.mozilla.xul+xml", "xul" }, | |
64 { "application/x-shockwave-flash", "swf,swl" } | |
65 }; | |
66 | |
67 // From http://www.w3schools.com/media/media_mimeref.asp and | |
68 // http://plugindoc.mozdev.org/winmime.php | |
69 static const char* kStandardImageTypes[] = { | |
70 "image/bmp", | |
71 "image/cis-cod", | |
72 "image/gif", | |
73 "image/ief", | |
74 "image/jpeg", | |
75 "image/pict", | |
76 "image/pipeg", | |
77 "image/png", | |
78 "image/svg+xml", | |
79 "image/tiff", | |
80 "image/x-cmu-raster", | |
81 "image/x-cmx", | |
82 "image/x-icon", | |
83 "image/x-portable-anymap", | |
84 "image/x-portable-bitmap", | |
85 "image/x-portable-graymap", | |
86 "image/x-portable-pixmap", | |
87 "image/x-rgb", | |
88 "image/x-xbitmap", | |
89 "image/x-xpixmap", | |
90 "image/x-xwindowdump" | |
91 }; | |
92 static const char* kStandardAudioTypes[] = { | |
93 "audio/aac", | |
94 "audio/aiff", | |
95 "audio/amr", | |
96 "audio/basic", | |
97 "audio/midi", | |
98 "audio/mp3", | |
99 "audio/mp4", | |
100 "audio/mpeg", | |
101 "audio/mpeg3", | |
102 "audio/ogg", | |
103 "audio/wav", | |
104 "audio/webm", | |
105 "audio/vorbis", | |
106 "audio/x-m4a", | |
107 "audio/x-ms-wma", | |
108 "audio/vnd.rn-realaudio", | |
109 "audio/vnd.wave" | |
110 }; | |
111 static const char* kStandardVideoTypes[] = { | |
112 "video/avi", | |
113 "video/divx", | |
114 "video/flc", | |
115 "video/mp4", | |
116 "video/mpeg", | |
117 "video/ogg", | |
118 "video/quicktime", | |
119 "video/sd-video", | |
120 "video/webm", | |
121 "video/x-dv", | |
122 "video/x-m4v", | |
123 "video/x-mpeg", | |
124 "video/x-ms-asf", | |
125 "video/x-ms-wmv" | |
126 }; | |
127 | |
128 void GetExtensionsFromHardCodedMappings( | |
129 const MimeInfo* mappings, | |
130 size_t mappings_len, | |
131 const std::string& leading_mime_type, | |
132 base::hash_set<FilePath::StringType>* extensions) { | |
133 FilePath::StringType extension; | |
134 for (size_t i = 0; i < mappings_len; ++i) { | |
135 if (StartsWithASCII(mappings[i].mime_type, leading_mime_type, false)) { | |
136 std::vector<string> this_extensions; | |
137 base::SplitStringUsingSubstr(mappings[i].extensions, | |
138 ",", | |
139 &this_extensions); | |
140 for (size_t j = 0; j < this_extensions.size(); ++j) { | |
141 #if defined(OS_WIN) | |
142 FilePath::StringType extension(UTF8ToWide(this_extensions[j])); | |
143 #else | |
144 FilePath::StringType extension(this_extensions[j]); | |
145 #endif | |
146 extensions->insert(extension); | |
147 } | |
148 } | |
149 } | |
150 } | |
151 | |
152 void GetExtensionsHelper( | |
153 const char** standard_types, | |
154 size_t standard_types_len, | |
155 const std::string& leading_mime_type, | |
156 base::hash_set<FilePath::StringType>* extensions) { | |
157 FilePath::StringType extension; | |
158 for (size_t i = 0; i < standard_types_len; ++i) { | |
159 if (net::GetPreferredExtensionForMimeType(standard_types[i], &extension)) | |
160 extensions->insert(extension); | |
161 } | |
162 | |
163 // Also look up the extensions from hard-coded mappings in case that some | |
164 // supported extensions are not registered in the system registry, like ogg. | |
165 GetExtensionsFromHardCodedMappings(kPrimaryMappings, | |
166 arraysize(kPrimaryMappings), | |
167 leading_mime_type, | |
168 extensions); | |
169 | |
170 GetExtensionsFromHardCodedMappings(kSecondaryMappings, | |
171 arraysize(kSecondaryMappings), | |
172 leading_mime_type, | |
173 extensions); | |
174 } | |
175 | |
176 // Notes: | |
177 // 1) The elements in the source set will be appended to the target vector. | |
178 // 2) The source set will be destroyed after this function returns. | |
179 template<class T> | |
180 void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) { | |
181 size_t old_target_size = target->size(); | |
182 target->resize(old_target_size + source->size()); | |
183 size_t i = 0; | |
184 for (base::hash_set<T>::iterator iter(source->begin()); | |
185 iter != source->end(); ++iter, ++i) { | |
186 target->at(old_target_size + i).swap(*iter); | |
187 } | |
188 source->clear(); | |
189 } | |
190 | |
191 } | |
192 | |
19 namespace net { | 193 namespace net { |
20 | 194 |
21 // Singleton utility class for mime types. | 195 // Singleton utility class for mime types. |
22 class MimeUtil : public PlatformMimeUtil { | 196 class MimeUtil : public PlatformMimeUtil { |
23 public: | 197 public: |
24 bool GetMimeTypeFromExtension(const FilePath::StringType& ext, | 198 bool GetMimeTypeFromExtension(const FilePath::StringType& ext, |
25 std::string* mime_type) const; | 199 std::string* mime_type) const; |
26 | 200 |
27 bool GetMimeTypeFromFile(const FilePath& file_path, | 201 bool GetMimeTypeFromFile(const FilePath& file_path, |
28 std::string* mime_type) const; | 202 std::string* mime_type) const; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 MimeMappings media_map_; | 237 MimeMappings media_map_; |
64 MimeMappings non_image_map_; | 238 MimeMappings non_image_map_; |
65 MimeMappings javascript_map_; | 239 MimeMappings javascript_map_; |
66 MimeMappings view_source_map_; | 240 MimeMappings view_source_map_; |
67 MimeMappings codecs_map_; | 241 MimeMappings codecs_map_; |
68 | 242 |
69 typedef std::map<std::string, base::hash_set<std::string> > StrictMappings; | 243 typedef std::map<std::string, base::hash_set<std::string> > StrictMappings; |
70 StrictMappings strict_format_map_; | 244 StrictMappings strict_format_map_; |
71 }; // class MimeUtil | 245 }; // class MimeUtil |
72 | 246 |
73 struct MimeInfo { | |
74 const char* mime_type; | |
75 const char* extensions; // comma separated list | |
76 }; | |
77 | |
78 static const MimeInfo primary_mappings[] = { | |
79 { "text/html", "html,htm" }, | |
80 { "text/css", "css" }, | |
81 { "text/xml", "xml" }, | |
82 { "image/gif", "gif" }, | |
83 { "image/jpeg", "jpeg,jpg" }, | |
84 { "image/png", "png" }, | |
85 { "video/mp4", "mp4,m4v" }, | |
86 { "audio/x-m4a", "m4a" }, | |
87 { "audio/mp3", "mp3" }, | |
88 { "video/ogg", "ogv,ogm" }, | |
89 { "audio/ogg", "ogg,oga" }, | |
90 { "video/webm", "webm" }, | |
91 { "audio/webm", "webm" }, | |
92 { "application/xhtml+xml", "xhtml,xht" }, | |
93 { "application/x-chrome-extension", "crx" } | |
94 }; | |
95 | |
96 static const MimeInfo secondary_mappings[] = { | |
97 { "application/octet-stream", "exe,com,bin" }, | |
98 { "application/gzip", "gz" }, | |
99 { "application/pdf", "pdf" }, | |
100 { "application/postscript", "ps,eps,ai" }, | |
101 { "application/x-javascript", "js" }, | |
102 { "image/bmp", "bmp" }, | |
103 { "image/x-icon", "ico" }, | |
104 { "image/jpeg", "jfif,pjpeg,pjp" }, | |
105 { "image/tiff", "tiff,tif" }, | |
106 { "image/x-xbitmap", "xbm" }, | |
107 { "image/svg+xml", "svg,svgz" }, | |
108 { "message/rfc822", "eml" }, | |
109 { "text/plain", "txt,text" }, | |
110 { "text/html", "shtml,ehtml" }, | |
111 { "application/rss+xml", "rss" }, | |
112 { "application/rdf+xml", "rdf" }, | |
113 { "text/xml", "xsl,xbl" }, | |
114 { "application/vnd.mozilla.xul+xml", "xul" }, | |
115 { "application/x-shockwave-flash", "swf,swl" } | |
116 }; | |
117 | |
118 static const char* FindMimeType(const MimeInfo* mappings, | 247 static const char* FindMimeType(const MimeInfo* mappings, |
119 size_t mappings_len, | 248 size_t mappings_len, |
120 const char* ext) { | 249 const char* ext) { |
121 size_t ext_len = strlen(ext); | 250 size_t ext_len = strlen(ext); |
122 | 251 |
123 for (size_t i = 0; i < mappings_len; ++i) { | 252 for (size_t i = 0; i < mappings_len; ++i) { |
124 const char* extensions = mappings[i].extensions; | 253 const char* extensions = mappings[i].extensions; |
125 for (;;) { | 254 for (;;) { |
126 size_t end_pos = strcspn(extensions, ","); | 255 size_t end_pos = strcspn(extensions, ","); |
127 if (end_pos == ext_len && | 256 if (end_pos == ext_len && |
(...skipping 21 matching lines...) Expand all Loading... | |
149 // Finally, we scan a secondary hard-coded list to catch types that we can | 278 // Finally, we scan a secondary hard-coded list to catch types that we can |
150 // deduce but that we also want to allow the OS to override. | 279 // deduce but that we also want to allow the OS to override. |
151 | 280 |
152 #if defined(OS_WIN) | 281 #if defined(OS_WIN) |
153 string ext_narrow_str = WideToUTF8(ext); | 282 string ext_narrow_str = WideToUTF8(ext); |
154 #elif defined(OS_POSIX) | 283 #elif defined(OS_POSIX) |
155 const string& ext_narrow_str = ext; | 284 const string& ext_narrow_str = ext; |
156 #endif | 285 #endif |
157 const char* mime_type; | 286 const char* mime_type; |
158 | 287 |
159 mime_type = FindMimeType(primary_mappings, arraysize(primary_mappings), | 288 mime_type = FindMimeType(kPrimaryMappings, arraysize(kPrimaryMappings), |
160 ext_narrow_str.c_str()); | 289 ext_narrow_str.c_str()); |
161 if (mime_type) { | 290 if (mime_type) { |
162 *result = mime_type; | 291 *result = mime_type; |
163 return true; | 292 return true; |
164 } | 293 } |
165 | 294 |
166 if (GetPlatformMimeTypeFromExtension(ext, result)) | 295 if (GetPlatformMimeTypeFromExtension(ext, result)) |
167 return true; | 296 return true; |
168 | 297 |
169 mime_type = FindMimeType(secondary_mappings, arraysize(secondary_mappings), | 298 mime_type = FindMimeType(kSecondaryMappings, arraysize(kSecondaryMappings), |
170 ext_narrow_str.c_str()); | 299 ext_narrow_str.c_str()); |
171 if (mime_type) { | 300 if (mime_type) { |
172 *result = mime_type; | 301 *result = mime_type; |
173 return true; | 302 return true; |
174 } | 303 } |
175 | 304 |
176 return false; | 305 return false; |
177 } | 306 } |
178 | 307 |
179 bool MimeUtil::GetMimeTypeFromFile(const FilePath& file_path, | 308 bool MimeUtil::GetMimeTypeFromFile(const FilePath& file_path, |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 const std::vector<std::string>& codecs) { | 653 const std::vector<std::string>& codecs) { |
525 return GetMimeUtil()->IsSupportedStrictMediaMimeType(mime_type, codecs); | 654 return GetMimeUtil()->IsSupportedStrictMediaMimeType(mime_type, codecs); |
526 } | 655 } |
527 | 656 |
528 void ParseCodecString(const std::string& codecs, | 657 void ParseCodecString(const std::string& codecs, |
529 std::vector<std::string>* codecs_out, | 658 std::vector<std::string>* codecs_out, |
530 const bool strip) { | 659 const bool strip) { |
531 GetMimeUtil()->ParseCodecString(codecs, codecs_out, strip); | 660 GetMimeUtil()->ParseCodecString(codecs, codecs_out, strip); |
532 } | 661 } |
533 | 662 |
663 void GetImageExtensions(std::vector<FilePath::StringType>* extensions) { | |
664 base::hash_set<FilePath::StringType> unique_extensions; | |
665 GetExtensionsHelper(kStandardImageTypes, | |
666 arraysize(kStandardImageTypes), | |
667 "image/", | |
668 &unique_extensions); | |
669 HashSetToVector(&unique_extensions, extensions); | |
670 } | |
671 | |
672 void GetAudioExtensions(std::vector<FilePath::StringType>* extensions) { | |
673 base::hash_set<FilePath::StringType> unique_extensions; | |
674 GetExtensionsHelper(kStandardAudioTypes, | |
675 arraysize(kStandardAudioTypes), | |
676 "audio/", | |
677 &unique_extensions); | |
678 HashSetToVector(&unique_extensions, extensions); | |
679 } | |
680 | |
681 void GetVideoExtensions(std::vector<FilePath::StringType>* extensions) { | |
682 base::hash_set<FilePath::StringType> unique_extensions; | |
683 GetExtensionsHelper(kStandardVideoTypes, | |
684 arraysize(kStandardVideoTypes), | |
685 "video/", | |
686 &unique_extensions); | |
687 HashSetToVector(&unique_extensions, extensions); | |
688 } | |
689 | |
690 void GetExtensionsForMimeType(const std::string& mime_type, | |
691 std::vector<FilePath::StringType>* extensions) { | |
692 base::hash_set<FilePath::StringType> unique_extensions; | |
693 FilePath::StringType extension; | |
694 if (net::GetPreferredExtensionForMimeType(mime_type, &extension)) | |
695 unique_extensions.insert(extension); | |
696 | |
697 // Also look up the extensions from hard-coded mappings in case that some | |
698 // supported extensions are not registered in the system registry, like ogg. | |
699 GetExtensionsFromHardCodedMappings(kPrimaryMappings, | |
700 arraysize(kPrimaryMappings), | |
701 mime_type, | |
702 &unique_extensions); | |
703 | |
704 GetExtensionsFromHardCodedMappings(kSecondaryMappings, | |
705 arraysize(kSecondaryMappings), | |
706 mime_type, | |
707 &unique_extensions); | |
708 | |
709 HashSetToVector(&unique_extensions, extensions); | |
710 } | |
711 | |
534 } // namespace net | 712 } // namespace net |
OLD | NEW |