Chromium Code Reviews| 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 |