OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 void ParseCodecString(const std::string& codecs, | 48 void ParseCodecString(const std::string& codecs, |
49 std::vector<std::string>* codecs_out, | 49 std::vector<std::string>* codecs_out, |
50 bool strip); | 50 bool strip); |
51 | 51 |
52 bool IsStrictMediaMimeType(const std::string& mime_type) const; | 52 bool IsStrictMediaMimeType(const std::string& mime_type) const; |
53 bool IsSupportedStrictMediaMimeType(const std::string& mime_type, | 53 bool IsSupportedStrictMediaMimeType(const std::string& mime_type, |
54 const std::vector<std::string>& codecs) const; | 54 const std::vector<std::string>& codecs) const; |
55 | 55 |
56 private: | 56 private: |
57 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; | 57 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; |
58 | 58 MimeUtil() { |
59 typedef base::hash_set<std::string> MimeMappings; | 59 InitializeMimeTypeMaps(); |
60 typedef std::map<std::string, MimeMappings> StrictMappings; | 60 } |
61 | |
62 MimeUtil(); | |
63 | |
64 // Returns true if |codecs| is nonempty and all the items in it are present in | |
65 // |supported_codecs|. | |
66 static bool AreSupportedCodecs(const MimeMappings& supported_codecs, | |
67 const std::vector<std::string>& codecs); | |
68 | 61 |
69 // For faster lookup, keep hash sets. | 62 // For faster lookup, keep hash sets. |
70 void InitializeMimeTypeMaps(); | 63 void InitializeMimeTypeMaps(); |
71 | 64 |
72 bool GetMimeTypeFromExtensionHelper(const FilePath::StringType& ext, | 65 bool GetMimeTypeFromExtensionHelper( |
73 bool include_platform_types, | 66 const FilePath::StringType& ext, bool include_platform_types, |
74 std::string* mime_type) const; | 67 std::string* mime_type) const; |
75 | 68 |
| 69 typedef base::hash_set<std::string> MimeMappings; |
76 MimeMappings image_map_; | 70 MimeMappings image_map_; |
77 MimeMappings media_map_; | 71 MimeMappings media_map_; |
78 MimeMappings non_image_map_; | 72 MimeMappings non_image_map_; |
79 MimeMappings javascript_map_; | 73 MimeMappings javascript_map_; |
80 MimeMappings view_source_map_; | 74 MimeMappings view_source_map_; |
81 MimeMappings codecs_map_; | 75 MimeMappings codecs_map_; |
82 | 76 |
| 77 typedef std::map<std::string, base::hash_set<std::string> > StrictMappings; |
83 StrictMappings strict_format_map_; | 78 StrictMappings strict_format_map_; |
84 }; // class MimeUtil | 79 }; // class MimeUtil |
85 | 80 |
86 static base::LazyInstance<MimeUtil> g_mime_util = LAZY_INSTANCE_INITIALIZER; | 81 static base::LazyInstance<MimeUtil> g_mime_util = LAZY_INSTANCE_INITIALIZER; |
87 | 82 |
88 struct MimeInfo { | 83 struct MimeInfo { |
89 const char* mime_type; | 84 const char* mime_type; |
90 const char* extensions; // comma separated list | 85 const char* extensions; // comma separated list |
91 }; | 86 }; |
92 | 87 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 151 } |
157 return NULL; | 152 return NULL; |
158 } | 153 } |
159 | 154 |
160 bool MimeUtil::GetMimeTypeFromExtension(const FilePath::StringType& ext, | 155 bool MimeUtil::GetMimeTypeFromExtension(const FilePath::StringType& ext, |
161 string* result) const { | 156 string* result) const { |
162 return GetMimeTypeFromExtensionHelper(ext, true, result); | 157 return GetMimeTypeFromExtensionHelper(ext, true, result); |
163 } | 158 } |
164 | 159 |
165 bool MimeUtil::GetWellKnownMimeTypeFromExtension( | 160 bool MimeUtil::GetWellKnownMimeTypeFromExtension( |
166 const FilePath::StringType& ext, | 161 const FilePath::StringType& ext, string* result) const { |
167 string* result) const { | |
168 return GetMimeTypeFromExtensionHelper(ext, false, result); | 162 return GetMimeTypeFromExtensionHelper(ext, false, result); |
169 } | 163 } |
170 | 164 |
171 bool MimeUtil::GetMimeTypeFromFile(const FilePath& file_path, | 165 bool MimeUtil::GetMimeTypeFromFile(const FilePath& file_path, |
172 string* result) const { | 166 string* result) const { |
173 FilePath::StringType file_name_str = file_path.Extension(); | 167 FilePath::StringType file_name_str = file_path.Extension(); |
174 if (file_name_str.empty()) | 168 if (file_name_str.empty()) |
175 return false; | 169 return false; |
176 return GetMimeTypeFromExtension(file_name_str.substr(1), result); | 170 return GetMimeTypeFromExtension(file_name_str.substr(1), result); |
177 } | 171 } |
178 | 172 |
179 bool MimeUtil::GetMimeTypeFromExtensionHelper(const FilePath::StringType& ext, | 173 bool MimeUtil::GetMimeTypeFromExtensionHelper( |
180 bool include_platform_types, | 174 const FilePath::StringType& ext, bool include_platform_types, |
181 string* result) const { | 175 string* result) const { |
182 // Avoids crash when unable to handle a long file path. See crbug.com/48733. | 176 // Avoids crash when unable to handle a long file path. See crbug.com/48733. |
183 const unsigned kMaxFilePathSize = 65536; | 177 const unsigned kMaxFilePathSize = 65536; |
184 if (ext.length() > kMaxFilePathSize) | 178 if (ext.length() > kMaxFilePathSize) |
185 return false; | 179 return false; |
186 | 180 |
187 // We implement the same algorithm as Mozilla for mapping a file extension to | 181 // We implement the same algorithm as Mozilla for mapping a file extension to |
188 // a mime type. That is, we first check a hard-coded list (that cannot be | 182 // a mime type. That is, we first check a hard-coded list (that cannot be |
189 // overridden), and then if not found there, we defer to the system registry. | 183 // overridden), and then if not found there, we defer to the system registry. |
190 // Finally, we scan a secondary hard-coded list to catch types that we can | 184 // Finally, we scan a secondary hard-coded list to catch types that we can |
191 // deduce but that we also want to allow the OS to override. | 185 // deduce but that we also want to allow the OS to override. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 const char* mime_type; | 339 const char* mime_type; |
346 const char* codecs_list; | 340 const char* codecs_list; |
347 }; | 341 }; |
348 | 342 |
349 static const MediaFormatStrict format_codec_mappings[] = { | 343 static const MediaFormatStrict format_codec_mappings[] = { |
350 { "video/webm", "vorbis,vp8,vp8.0" }, | 344 { "video/webm", "vorbis,vp8,vp8.0" }, |
351 { "audio/webm", "vorbis" }, | 345 { "audio/webm", "vorbis" }, |
352 { "audio/wav", "1" } | 346 { "audio/wav", "1" } |
353 }; | 347 }; |
354 | 348 |
355 MimeUtil::MimeUtil() { | |
356 InitializeMimeTypeMaps(); | |
357 } | |
358 | |
359 // static | |
360 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, | |
361 const std::vector<std::string>& codecs) { | |
362 for (size_t i = 0; i < codecs.size(); ++i) { | |
363 if (supported_codecs.find(codecs[i]) == supported_codecs.end()) | |
364 return false; | |
365 } | |
366 return !codecs.empty(); | |
367 } | |
368 | |
369 void MimeUtil::InitializeMimeTypeMaps() { | 349 void MimeUtil::InitializeMimeTypeMaps() { |
370 for (size_t i = 0; i < arraysize(supported_image_types); ++i) | 350 for (size_t i = 0; i < arraysize(supported_image_types); ++i) |
371 image_map_.insert(supported_image_types[i]); | 351 image_map_.insert(supported_image_types[i]); |
372 | 352 |
373 // Initialize the supported non-image types. | 353 // Initialize the supported non-image types. |
374 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) | 354 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) |
375 non_image_map_.insert(supported_non_image_types[i]); | 355 non_image_map_.insert(supported_non_image_types[i]); |
376 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) | 356 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) |
377 non_image_map_.insert(supported_javascript_types[i]); | 357 non_image_map_.insert(supported_javascript_types[i]); |
378 for (size_t i = 0; i < arraysize(supported_media_types); ++i) | 358 for (size_t i = 0; i < arraysize(supported_media_types); ++i) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 return view_source_map_.find(mime_type) != view_source_map_.end(); | 405 return view_source_map_.find(mime_type) != view_source_map_.end(); |
426 } | 406 } |
427 | 407 |
428 // Mirrors WebViewImpl::CanShowMIMEType() | 408 // Mirrors WebViewImpl::CanShowMIMEType() |
429 bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const { | 409 bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const { |
430 return (mime_type.compare(0, 6, "image/") == 0 && | 410 return (mime_type.compare(0, 6, "image/") == 0 && |
431 IsSupportedImageMimeType(mime_type.c_str())) || | 411 IsSupportedImageMimeType(mime_type.c_str())) || |
432 IsSupportedNonImageMimeType(mime_type.c_str()); | 412 IsSupportedNonImageMimeType(mime_type.c_str()); |
433 } | 413 } |
434 | 414 |
435 bool MimeUtil::MatchesMimeType(const std::string& mime_type_pattern, | 415 bool MimeUtil::MatchesMimeType(const std::string &mime_type_pattern, |
436 const std::string& mime_type) const { | 416 const std::string &mime_type) const { |
437 // verify caller is passing lowercase | 417 // verify caller is passing lowercase |
438 DCHECK_EQ(StringToLowerASCII(mime_type_pattern), mime_type_pattern); | 418 DCHECK_EQ(StringToLowerASCII(mime_type_pattern), mime_type_pattern); |
439 DCHECK_EQ(StringToLowerASCII(mime_type), mime_type); | 419 DCHECK_EQ(StringToLowerASCII(mime_type), mime_type); |
440 | 420 |
441 // This comparison handles absolute maching and also basic | 421 // This comparison handles absolute maching and also basic |
442 // wildcards. The plugin mime types could be: | 422 // wildcards. The plugin mime types could be: |
443 // application/x-foo | 423 // application/x-foo |
444 // application/* | 424 // application/* |
445 // application/*+xml | 425 // application/*+xml |
446 // * | 426 // * |
(...skipping 17 matching lines...) Expand all Loading... |
464 | 444 |
465 if (!right.empty() && | 445 if (!right.empty() && |
466 mime_type.rfind(right) != mime_type.length() - right.length()) | 446 mime_type.rfind(right) != mime_type.length() - right.length()) |
467 return false; | 447 return false; |
468 | 448 |
469 return true; | 449 return true; |
470 } | 450 } |
471 | 451 |
472 bool MimeUtil::AreSupportedMediaCodecs( | 452 bool MimeUtil::AreSupportedMediaCodecs( |
473 const std::vector<std::string>& codecs) const { | 453 const std::vector<std::string>& codecs) const { |
474 return AreSupportedCodecs(codecs_map_, codecs); | 454 for (size_t i = 0; i < codecs.size(); ++i) { |
| 455 if (codecs_map_.find(codecs[i]) == codecs_map_.end()) { |
| 456 return false; |
| 457 } |
| 458 } |
| 459 return true; |
475 } | 460 } |
476 | 461 |
477 void MimeUtil::ParseCodecString(const std::string& codecs, | 462 void MimeUtil::ParseCodecString(const std::string& codecs, |
478 std::vector<std::string>* codecs_out, | 463 std::vector<std::string>* codecs_out, |
479 bool strip) { | 464 bool strip) { |
480 std::string no_quote_codecs; | 465 std::string no_quote_codecs; |
481 TrimString(codecs, "\"", &no_quote_codecs); | 466 TrimString(codecs, "\"", &no_quote_codecs); |
482 base::SplitString(no_quote_codecs, ',', codecs_out); | 467 base::SplitString(no_quote_codecs, ',', codecs_out); |
483 | 468 |
484 if (!strip) | 469 if (!strip) |
485 return; | 470 return; |
486 | 471 |
487 // Strip everything past the first '.' | 472 // Strip everything past the first '.' |
488 for (std::vector<std::string>::iterator it = codecs_out->begin(); | 473 for (std::vector<std::string>::iterator it = codecs_out->begin(); |
489 it != codecs_out->end(); | 474 it != codecs_out->end(); |
490 ++it) { | 475 ++it) { |
491 size_t found = it->find_first_of('.'); | 476 size_t found = it->find_first_of('.'); |
492 if (found != std::string::npos) | 477 if (found != std::string::npos) |
493 it->resize(found); | 478 it->resize(found); |
494 } | 479 } |
495 } | 480 } |
496 | 481 |
497 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { | 482 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { |
498 if (strict_format_map_.find(mime_type) == strict_format_map_.end()) | 483 if (strict_format_map_.find(mime_type) == strict_format_map_.end()) |
499 return false; | 484 return false; |
500 return true; | 485 return true; |
501 } | 486 } |
502 | 487 |
503 bool MimeUtil::IsSupportedStrictMediaMimeType( | 488 bool MimeUtil::IsSupportedStrictMediaMimeType(const std::string& mime_type, |
504 const std::string& mime_type, | |
505 const std::vector<std::string>& codecs) const { | 489 const std::vector<std::string>& codecs) const { |
506 StrictMappings::const_iterator it = strict_format_map_.find(mime_type); | 490 StrictMappings::const_iterator it = strict_format_map_.find(mime_type); |
507 return (it != strict_format_map_.end()) && | 491 |
508 AreSupportedCodecs(it->second, codecs); | 492 if (it == strict_format_map_.end()) |
| 493 return false; |
| 494 |
| 495 const MimeMappings strict_codecs_map = it->second; |
| 496 for (size_t i = 0; i < codecs.size(); ++i) { |
| 497 if (strict_codecs_map.find(codecs[i]) == strict_codecs_map.end()) { |
| 498 return false; |
| 499 } |
| 500 } |
| 501 return true; |
509 } | 502 } |
510 | 503 |
511 //---------------------------------------------------------------------------- | 504 //---------------------------------------------------------------------------- |
512 // Wrappers for the singleton | 505 // Wrappers for the singleton |
513 //---------------------------------------------------------------------------- | 506 //---------------------------------------------------------------------------- |
514 | 507 |
515 bool GetMimeTypeFromExtension(const FilePath::StringType& ext, | 508 bool GetMimeTypeFromExtension(const FilePath::StringType& ext, |
516 std::string* mime_type) { | 509 std::string* mime_type) { |
517 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type); | 510 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type); |
518 } | 511 } |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 | 742 |
750 GetExtensionsFromHardCodedMappings(secondary_mappings, | 743 GetExtensionsFromHardCodedMappings(secondary_mappings, |
751 arraysize(secondary_mappings), | 744 arraysize(secondary_mappings), |
752 mime_type, | 745 mime_type, |
753 &unique_extensions); | 746 &unique_extensions); |
754 | 747 |
755 HashSetToVector(&unique_extensions, extensions); | 748 HashSetToVector(&unique_extensions, extensions); |
756 } | 749 } |
757 | 750 |
758 } // namespace net | 751 } // namespace net |
OLD | NEW |