| 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <iterator> | 6 #include <iterator> |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "net/base/mime_util.h" | 17 #include "net/base/mime_util.h" |
| 18 #include "net/base/platform_mime_util.h" | 18 #include "net/base/platform_mime_util.h" |
| 19 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 20 | 20 |
| 21 #if defined(OS_ANDROID) | |
| 22 #include "base/android/build_info.h" | |
| 23 #endif | |
| 24 | |
| 25 using std::string; | 21 using std::string; |
| 26 | 22 |
| 27 namespace { | 23 namespace { |
| 28 | 24 |
| 29 struct MediaType { | 25 struct MediaType { |
| 30 const char name[12]; | 26 const char name[12]; |
| 31 const char matcher[13]; | 27 const char matcher[13]; |
| 32 }; | 28 }; |
| 33 | 29 |
| 34 static const MediaType kIanaMediaTypes[] = { | 30 static const MediaType kIanaMediaTypes[] = { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 53 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, | 49 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, |
| 54 std::string* mime_type) const; | 50 std::string* mime_type) const; |
| 55 | 51 |
| 56 bool GetMimeTypeFromFile(const base::FilePath& file_path, | 52 bool GetMimeTypeFromFile(const base::FilePath& file_path, |
| 57 std::string* mime_type) const; | 53 std::string* mime_type) const; |
| 58 | 54 |
| 59 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext, | 55 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext, |
| 60 std::string* mime_type) const; | 56 std::string* mime_type) const; |
| 61 | 57 |
| 62 bool IsSupportedImageMimeType(const std::string& mime_type) const; | 58 bool IsSupportedImageMimeType(const std::string& mime_type) const; |
| 63 bool IsSupportedMediaMimeType(const std::string& mime_type) const; | |
| 64 bool IsSupportedNonImageMimeType(const std::string& mime_type) const; | 59 bool IsSupportedNonImageMimeType(const std::string& mime_type) const; |
| 65 bool IsUnsupportedTextMimeType(const std::string& mime_type) const; | 60 bool IsUnsupportedTextMimeType(const std::string& mime_type) const; |
| 66 bool IsSupportedJavascriptMimeType(const std::string& mime_type) const; | 61 bool IsSupportedJavascriptMimeType(const std::string& mime_type) const; |
| 67 | 62 |
| 68 bool IsSupportedMimeType(const std::string& mime_type) const; | 63 bool IsSupportedMimeType(const std::string& mime_type) const; |
| 69 | 64 |
| 70 bool MatchesMimeType(const std::string &mime_type_pattern, | 65 bool MatchesMimeType(const std::string &mime_type_pattern, |
| 71 const std::string &mime_type) const; | 66 const std::string &mime_type) const; |
| 72 | 67 |
| 73 bool ParseMimeTypeWithoutParameter(const std::string& type_string, | 68 bool ParseMimeTypeWithoutParameter(const std::string& type_string, |
| 74 std::string* top_level_type, | 69 std::string* top_level_type, |
| 75 std::string* subtype) const; | 70 std::string* subtype) const; |
| 76 | 71 |
| 77 bool IsValidTopLevelMimeType(const std::string& type_string) const; | 72 bool IsValidTopLevelMimeType(const std::string& type_string) const; |
| 78 | 73 |
| 79 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) const; | |
| 80 | |
| 81 void ParseCodecString(const std::string& codecs, | |
| 82 std::vector<std::string>* codecs_out, | |
| 83 bool strip); | |
| 84 | |
| 85 bool IsStrictMediaMimeType(const std::string& mime_type) const; | |
| 86 SupportsType IsSupportedStrictMediaMimeType( | |
| 87 const std::string& mime_type, | |
| 88 const std::vector<std::string>& codecs) const; | |
| 89 | |
| 90 void RemoveProprietaryMediaTypesAndCodecsForTests(); | |
| 91 | |
| 92 private: | 74 private: |
| 93 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; | 75 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; |
| 94 | 76 |
| 95 typedef base::hash_set<std::string> MimeMappings; | 77 typedef base::hash_set<std::string> MimeMappings; |
| 96 typedef std::map<std::string, MimeMappings> StrictMappings; | |
| 97 | |
| 98 typedef std::vector<std::string> MimeExpressionMappings; | |
| 99 typedef std::map<std::string, MimeExpressionMappings> | |
| 100 StrictExpressionMappings; | |
| 101 | 78 |
| 102 MimeUtil(); | 79 MimeUtil(); |
| 103 | 80 |
| 104 // Returns true if |codecs| is nonempty and all the items in it are present in | |
| 105 // |supported_codecs|. | |
| 106 static bool AreSupportedCodecs(const MimeMappings& supported_codecs, | |
| 107 const std::vector<std::string>& codecs); | |
| 108 // Returns true is |codecs| is nonempty and all the items in it match with the | |
| 109 // codecs expression in |supported_codecs|. | |
| 110 static bool AreSupportedCodecsWithProfile( | |
| 111 const MimeExpressionMappings& supported_codecs, | |
| 112 const std::vector<std::string>& codecs); | |
| 113 | |
| 114 // For faster lookup, keep hash sets. | 81 // For faster lookup, keep hash sets. |
| 115 void InitializeMimeTypeMaps(); | 82 void InitializeMimeTypeMaps(); |
| 116 | 83 |
| 117 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext, | 84 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext, |
| 118 bool include_platform_types, | 85 bool include_platform_types, |
| 119 std::string* mime_type) const; | 86 std::string* mime_type) const; |
| 120 | 87 |
| 121 MimeMappings image_map_; | 88 MimeMappings image_map_; |
| 122 MimeMappings media_map_; | |
| 123 MimeMappings non_image_map_; | 89 MimeMappings non_image_map_; |
| 124 MimeMappings unsupported_text_map_; | 90 MimeMappings unsupported_text_map_; |
| 125 MimeMappings javascript_map_; | 91 MimeMappings javascript_map_; |
| 126 MimeMappings codecs_map_; | |
| 127 | |
| 128 // A map of mime_types and hash map of the supported codecs for the mime_type. | |
| 129 StrictMappings strict_format_map_; | |
| 130 // A map of MP4 mime_types which expect codecs with profile parameter and | |
| 131 // vector of supported codecs expressions for the mime_type. | |
| 132 StrictExpressionMappings strict_mp4_format_map_; | |
| 133 }; // class MimeUtil | 92 }; // class MimeUtil |
| 134 | 93 |
| 135 // This variable is Leaky because we need to access it from WorkerPool threads. | 94 // This variable is Leaky because we need to access it from WorkerPool threads. |
| 136 static base::LazyInstance<MimeUtil>::Leaky g_mime_util = | 95 static base::LazyInstance<MimeUtil>::Leaky g_mime_util = |
| 137 LAZY_INSTANCE_INITIALIZER; | 96 LAZY_INSTANCE_INITIALIZER; |
| 138 | 97 |
| 139 struct MimeInfo { | 98 struct MimeInfo { |
| 140 const char* mime_type; | 99 const char* mime_type; |
| 141 const char* extensions; // comma separated list | 100 const char* extensions; // comma separated list |
| 142 }; | 101 }; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 "image/webp", | 235 "image/webp", |
| 277 "image/png", | 236 "image/png", |
| 278 "image/gif", | 237 "image/gif", |
| 279 "image/bmp", | 238 "image/bmp", |
| 280 "image/vnd.microsoft.icon", // ico | 239 "image/vnd.microsoft.icon", // ico |
| 281 "image/x-icon", // ico | 240 "image/x-icon", // ico |
| 282 "image/x-xbitmap", // xbm | 241 "image/x-xbitmap", // xbm |
| 283 "image/x-png" | 242 "image/x-png" |
| 284 }; | 243 }; |
| 285 | 244 |
| 286 // A list of media types: http://en.wikipedia.org/wiki/Internet_media_type | |
| 287 // A comprehensive mime type list: http://plugindoc.mozdev.org/winmime.php | |
| 288 // This set of codecs is supported by all variations of Chromium. | |
| 289 static const char* const common_media_types[] = { | |
| 290 // Ogg. | |
| 291 "audio/ogg", | |
| 292 "application/ogg", | |
| 293 #if !defined(OS_ANDROID) // Android doesn't support Ogg Theora. | |
| 294 "video/ogg", | |
| 295 #endif | |
| 296 | |
| 297 // WebM. | |
| 298 "video/webm", | |
| 299 "audio/webm", | |
| 300 | |
| 301 // Wav. | |
| 302 "audio/wav", | |
| 303 "audio/x-wav", | |
| 304 | |
| 305 #if defined(OS_ANDROID) | |
| 306 // HLS. Supported by Android ICS and above. | |
| 307 "application/vnd.apple.mpegurl", | |
| 308 "application/x-mpegurl", | |
| 309 #endif | |
| 310 }; | |
| 311 | |
| 312 // List of proprietary types only supported by Google Chrome. | |
| 313 static const char* const proprietary_media_types[] = { | |
| 314 // MPEG-4. | |
| 315 "video/mp4", | |
| 316 "video/x-m4v", | |
| 317 "audio/mp4", | |
| 318 "audio/x-m4a", | |
| 319 | |
| 320 // MP3. | |
| 321 "audio/mp3", | |
| 322 "audio/x-mp3", | |
| 323 "audio/mpeg", | |
| 324 }; | |
| 325 | |
| 326 // List of supported codecs when passed in with <source type="...">. | |
| 327 // This set of codecs is supported by all variations of Chromium. | |
| 328 // | |
| 329 // Refer to http://wiki.whatwg.org/wiki/Video_type_parameters#Browser_Support | |
| 330 // for more information. | |
| 331 // | |
| 332 // The codecs for WAV are integers as defined in Appendix A of RFC2361: | |
| 333 // http://tools.ietf.org/html/rfc2361 | |
| 334 static const char* const common_media_codecs[] = { | |
| 335 #if !defined(OS_ANDROID) // Android doesn't support Ogg Theora. | |
| 336 "theora", | |
| 337 #endif | |
| 338 "opus", | |
| 339 "vorbis", | |
| 340 "vp8", | |
| 341 "vp9", | |
| 342 "1" // WAVE_FORMAT_PCM. | |
| 343 }; | |
| 344 | |
| 345 // List of proprietary codecs only supported by Google Chrome. | |
| 346 static const char* const proprietary_media_codecs[] = { | |
| 347 "avc1", | |
| 348 "avc3", | |
| 349 "mp4a" | |
| 350 }; | |
| 351 | 245 |
| 352 // Note: | 246 // Note: |
| 353 // - does not include javascript types list (see supported_javascript_types) | 247 // - does not include javascript types list (see supported_javascript_types) |
| 354 // - does not include types starting with "text/" (see | 248 // - does not include types starting with "text/" (see |
| 355 // IsSupportedNonImageMimeType()) | 249 // IsSupportedNonImageMimeType()) |
| 356 static const char* const supported_non_image_types[] = { | 250 static const char* const supported_non_image_types[] = { |
| 357 "image/svg+xml", // SVG is text-based XML, even though it has an image/ type | 251 "image/svg+xml", // SVG is text-based XML, even though it has an image/ type |
| 358 "application/xml", | 252 "application/xml", |
| 359 "application/atom+xml", | 253 "application/atom+xml", |
| 360 "application/rss+xml", | 254 "application/rss+xml", |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 "application/javascript", | 316 "application/javascript", |
| 423 "application/ecmascript", | 317 "application/ecmascript", |
| 424 "application/x-javascript", | 318 "application/x-javascript", |
| 425 "text/javascript1.1", | 319 "text/javascript1.1", |
| 426 "text/javascript1.2", | 320 "text/javascript1.2", |
| 427 "text/javascript1.3", | 321 "text/javascript1.3", |
| 428 "text/jscript", | 322 "text/jscript", |
| 429 "text/livescript" | 323 "text/livescript" |
| 430 }; | 324 }; |
| 431 | 325 |
| 432 #if defined(OS_ANDROID) | |
| 433 static bool IsCodecSupportedOnAndroid(const std::string& codec) { | |
| 434 // Theora is not supported in Android | |
| 435 if (!codec.compare("theora")) | |
| 436 return false; | |
| 437 | |
| 438 // VP9 is supported only in KitKat+ (API Level 19). | |
| 439 if ((!codec.compare("vp9") || !codec.compare("vp9.0")) && | |
| 440 base::android::BuildInfo::GetInstance()->sdk_int() < 19) { | |
| 441 return false; | |
| 442 } | |
| 443 | |
| 444 // TODO(vigneshv): Change this similar to the VP9 check once Opus is | |
| 445 // supported on Android (http://crbug.com/318436). | |
| 446 if (!codec.compare("opus")) { | |
| 447 return false; | |
| 448 } | |
| 449 return true; | |
| 450 } | |
| 451 | |
| 452 static bool IsMimeTypeSupportedOnAndroid(const std::string& mimeType) { | |
| 453 // HLS codecs are supported in ICS and above (API level 14) | |
| 454 if ((!mimeType.compare("application/vnd.apple.mpegurl") || | |
| 455 !mimeType.compare("application/x-mpegurl")) && | |
| 456 base::android::BuildInfo::GetInstance()->sdk_int() < 14) { | |
| 457 return false; | |
| 458 } | |
| 459 return true; | |
| 460 } | |
| 461 #endif | |
| 462 | |
| 463 struct MediaFormatStrict { | |
| 464 const char* mime_type; | |
| 465 const char* codecs_list; | |
| 466 }; | |
| 467 | |
| 468 static const MediaFormatStrict format_codec_mappings[] = { | |
| 469 { "video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0" }, | |
| 470 { "audio/webm", "opus,vorbis" }, | |
| 471 { "audio/wav", "1" }, | |
| 472 { "audio/x-wav", "1" }, | |
| 473 { "video/ogg", "opus,theora,vorbis" }, | |
| 474 { "audio/ogg", "opus,vorbis" }, | |
| 475 { "application/ogg", "opus,theora,vorbis" }, | |
| 476 { "audio/mpeg", ",mp3" }, // Note: The comma before the 'mp3'results in an | |
| 477 // empty string codec ID and indicates | |
| 478 // a missing codecs= parameter is also valid. | |
| 479 // The presense of 'mp3' is not RFC compliant, | |
| 480 // but is common in the wild so it is a defacto | |
| 481 // standard. | |
| 482 { "audio/mp3", "" }, | |
| 483 { "audio/x-mp3", "" } | |
| 484 }; | |
| 485 | |
| 486 // Following is the list of RFC 6381 compliant codecs: | |
| 487 // mp4a.6B - MPEG-1 audio | |
| 488 // mp4a.69 - MPEG-2 extension to MPEG-1 | |
| 489 // mp4a.67 - MPEG-2 AAC | |
| 490 // mp4a.40.2 - MPEG-4 AAC | |
| 491 // mp4a.40.5 - MPEG-4 HE-AAC | |
| 492 // | |
| 493 // avc1.42E0xx - H.264 Baseline | |
| 494 // avc1.4D40xx - H.264 Main | |
| 495 // avc1.6400xx - H.264 High | |
| 496 // | |
| 497 // Additionally, several non-RFC compliant codecs are allowed, due to their | |
| 498 // existing use on web. | |
| 499 // mp4a.40 | |
| 500 // avc1.xxxxxx | |
| 501 // avc3.xxxxxx | |
| 502 // mp4a.6x | |
| 503 static const char kProprietaryAudioCodecsExpression[] = | |
| 504 "mp4a.6?,mp4a.40,mp4a.40.?"; | |
| 505 static const char kProprietaryCodecsExpression[] = | |
| 506 "avc1,avc3,avc1.??????,avc3.??????,mp4a.6?,mp4a.40,mp4a.40.?"; | |
| 507 | |
| 508 static const MediaFormatStrict format_mp4_codec_mappings[] = { | |
| 509 { "audio/mp4", kProprietaryAudioCodecsExpression }, | |
| 510 { "audio/x-m4a", kProprietaryAudioCodecsExpression }, | |
| 511 { "video/mp4", kProprietaryCodecsExpression }, | |
| 512 { "video/x-m4v", kProprietaryCodecsExpression }, | |
| 513 { "application/x-mpegurl", kProprietaryCodecsExpression }, | |
| 514 { "application/vnd.apple.mpegurl", kProprietaryCodecsExpression } | |
| 515 }; | |
| 516 | |
| 517 MimeUtil::MimeUtil() { | 326 MimeUtil::MimeUtil() { |
| 518 InitializeMimeTypeMaps(); | 327 InitializeMimeTypeMaps(); |
| 519 } | 328 } |
| 520 | 329 |
| 521 // static | |
| 522 bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, | |
| 523 const std::vector<std::string>& codecs) { | |
| 524 if (supported_codecs.empty()) | |
| 525 return codecs.empty(); | |
| 526 | |
| 527 // If no codecs are specified in the mimetype, check to see if a missing | |
| 528 // codecs parameter is allowed. | |
| 529 if (codecs.empty()) | |
| 530 return supported_codecs.find(std::string()) != supported_codecs.end(); | |
| 531 | |
| 532 for (size_t i = 0; i < codecs.size(); ++i) { | |
| 533 if (codecs[i].empty() || | |
| 534 supported_codecs.find(codecs[i]) == supported_codecs.end()) { | |
| 535 return false; | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 return true; | |
| 540 } | |
| 541 | |
| 542 // Checks all the codecs present in the |codecs| against the entries in | |
| 543 // |supported_codecs|. Returns true only if |codecs| is non-empty and all the | |
| 544 // codecs match |supported_codecs| expressions. | |
| 545 bool MimeUtil::AreSupportedCodecsWithProfile( | |
| 546 const MimeExpressionMappings& supported_codecs, | |
| 547 const std::vector<std::string>& codecs) { | |
| 548 DCHECK(!supported_codecs.empty()); | |
| 549 for (size_t i = 0; i < codecs.size(); ++i) { | |
| 550 bool codec_matched = false; | |
| 551 for (size_t j = 0; j < supported_codecs.size(); ++j) { | |
| 552 if (!MatchPattern(base::StringPiece(codecs[i]), | |
| 553 base::StringPiece(supported_codecs[j]))) { | |
| 554 continue; | |
| 555 } | |
| 556 // If suffix exists, check whether it is hexadecimal. | |
| 557 for (size_t wildcard_pos = supported_codecs[j].find('?'); | |
| 558 wildcard_pos != std::string::npos && | |
| 559 wildcard_pos < supported_codecs[j].length(); | |
| 560 wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) { | |
| 561 // Don't enforce case sensitivity, even though it's called for, as it | |
| 562 // would break some websites. | |
| 563 if (wildcard_pos >= codecs[i].length() || | |
| 564 !IsHexDigit(codecs[i].at(wildcard_pos))) { | |
| 565 return false; | |
| 566 } | |
| 567 } | |
| 568 codec_matched = true; | |
| 569 break; | |
| 570 } | |
| 571 if (!codec_matched) | |
| 572 return false; | |
| 573 } | |
| 574 return !codecs.empty(); | |
| 575 } | |
| 576 | |
| 577 void MimeUtil::InitializeMimeTypeMaps() { | 330 void MimeUtil::InitializeMimeTypeMaps() { |
| 578 for (size_t i = 0; i < arraysize(supported_image_types); ++i) | 331 for (size_t i = 0; i < arraysize(supported_image_types); ++i) |
| 579 image_map_.insert(supported_image_types[i]); | 332 image_map_.insert(supported_image_types[i]); |
| 580 | 333 |
| 581 // Initialize the supported non-image types. | 334 // Initialize the supported non-image types. |
| 582 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) | 335 for (size_t i = 0; i < arraysize(supported_non_image_types); ++i) |
| 583 non_image_map_.insert(supported_non_image_types[i]); | 336 non_image_map_.insert(supported_non_image_types[i]); |
| 584 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) | 337 for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) |
| 585 non_image_map_.insert(supported_certificate_types[i].mime_type); | 338 non_image_map_.insert(supported_certificate_types[i].mime_type); |
| 586 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i) | 339 for (size_t i = 0; i < arraysize(unsupported_text_types); ++i) |
| 587 unsupported_text_map_.insert(unsupported_text_types[i]); | 340 unsupported_text_map_.insert(unsupported_text_types[i]); |
| 588 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) | 341 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) |
| 589 non_image_map_.insert(supported_javascript_types[i]); | 342 non_image_map_.insert(supported_javascript_types[i]); |
| 590 for (size_t i = 0; i < arraysize(common_media_types); ++i) { | |
| 591 #if defined(OS_ANDROID) | |
| 592 if (!IsMimeTypeSupportedOnAndroid(common_media_types[i])) | |
| 593 continue; | |
| 594 #endif | |
| 595 non_image_map_.insert(common_media_types[i]); | |
| 596 } | |
| 597 #if defined(USE_PROPRIETARY_CODECS) | |
| 598 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) | |
| 599 non_image_map_.insert(proprietary_media_types[i]); | |
| 600 #endif | |
| 601 | |
| 602 // Initialize the supported media types. | |
| 603 for (size_t i = 0; i < arraysize(common_media_types); ++i) { | |
| 604 #if defined(OS_ANDROID) | |
| 605 if (!IsMimeTypeSupportedOnAndroid(common_media_types[i])) | |
| 606 continue; | |
| 607 #endif | |
| 608 media_map_.insert(common_media_types[i]); | |
| 609 } | |
| 610 #if defined(USE_PROPRIETARY_CODECS) | |
| 611 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) | |
| 612 media_map_.insert(proprietary_media_types[i]); | |
| 613 #endif | |
| 614 | |
| 615 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) | 343 for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) |
| 616 javascript_map_.insert(supported_javascript_types[i]); | 344 javascript_map_.insert(supported_javascript_types[i]); |
| 617 | |
| 618 for (size_t i = 0; i < arraysize(common_media_codecs); ++i) { | |
| 619 #if defined(OS_ANDROID) | |
| 620 if (!IsCodecSupportedOnAndroid(common_media_codecs[i])) | |
| 621 continue; | |
| 622 #endif | |
| 623 codecs_map_.insert(common_media_codecs[i]); | |
| 624 } | |
| 625 #if defined(USE_PROPRIETARY_CODECS) | |
| 626 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) | |
| 627 codecs_map_.insert(proprietary_media_codecs[i]); | |
| 628 #endif | |
| 629 | |
| 630 // Initialize the strict supported media types. | |
| 631 for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) { | |
| 632 std::vector<std::string> mime_type_codecs; | |
| 633 ParseCodecString(format_codec_mappings[i].codecs_list, | |
| 634 &mime_type_codecs, | |
| 635 false); | |
| 636 | |
| 637 MimeMappings codecs; | |
| 638 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { | |
| 639 #if defined(OS_ANDROID) | |
| 640 if (!IsCodecSupportedOnAndroid(mime_type_codecs[j])) | |
| 641 continue; | |
| 642 #endif | |
| 643 codecs.insert(mime_type_codecs[j]); | |
| 644 } | |
| 645 strict_format_map_[format_codec_mappings[i].mime_type] = codecs; | |
| 646 } | |
| 647 for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) { | |
| 648 std::vector<std::string> mime_type_codecs; | |
| 649 ParseCodecString( | |
| 650 format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false); | |
| 651 | |
| 652 MimeExpressionMappings codecs; | |
| 653 for (size_t j = 0; j < mime_type_codecs.size(); ++j) | |
| 654 codecs.push_back(mime_type_codecs[j]); | |
| 655 strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs; | |
| 656 } | |
| 657 } | 345 } |
| 658 | 346 |
| 659 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { | 347 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { |
| 660 return image_map_.find(mime_type) != image_map_.end(); | 348 return image_map_.find(mime_type) != image_map_.end(); |
| 661 } | 349 } |
| 662 | 350 |
| 663 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { | |
| 664 return media_map_.find(mime_type) != media_map_.end(); | |
| 665 } | |
| 666 | |
| 667 bool MimeUtil::IsSupportedNonImageMimeType(const std::string& mime_type) const { | 351 bool MimeUtil::IsSupportedNonImageMimeType(const std::string& mime_type) const { |
| 668 return non_image_map_.find(mime_type) != non_image_map_.end() || | 352 return non_image_map_.find(mime_type) != non_image_map_.end() || |
| 669 (mime_type.compare(0, 5, "text/") == 0 && | 353 (mime_type.compare(0, 5, "text/") == 0 && |
| 670 !IsUnsupportedTextMimeType(mime_type)) || | 354 !IsUnsupportedTextMimeType(mime_type)) || |
| 671 (mime_type.compare(0, 12, "application/") == 0 && | 355 (mime_type.compare(0, 12, "application/") == 0 && |
| 672 MatchesMimeType("application/*+json", mime_type)); | 356 MatchesMimeType("application/*+json", mime_type)); |
| 673 } | 357 } |
| 674 | 358 |
| 675 bool MimeUtil::IsUnsupportedTextMimeType(const std::string& mime_type) const { | 359 bool MimeUtil::IsUnsupportedTextMimeType(const std::string& mime_type) const { |
| 676 return unsupported_text_map_.find(mime_type) != unsupported_text_map_.end(); | 360 return unsupported_text_map_.find(mime_type) != unsupported_text_map_.end(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const { | 485 bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const { |
| 802 std::string lower_type = StringToLowerASCII(type_string); | 486 std::string lower_type = StringToLowerASCII(type_string); |
| 803 for (size_t i = 0; i < arraysize(legal_top_level_types); ++i) { | 487 for (size_t i = 0; i < arraysize(legal_top_level_types); ++i) { |
| 804 if (lower_type.compare(legal_top_level_types[i]) == 0) | 488 if (lower_type.compare(legal_top_level_types[i]) == 0) |
| 805 return true; | 489 return true; |
| 806 } | 490 } |
| 807 | 491 |
| 808 return type_string.size() > 2 && StartsWithASCII(type_string, "x-", false); | 492 return type_string.size() > 2 && StartsWithASCII(type_string, "x-", false); |
| 809 } | 493 } |
| 810 | 494 |
| 811 bool MimeUtil::AreSupportedMediaCodecs( | |
| 812 const std::vector<std::string>& codecs) const { | |
| 813 return AreSupportedCodecs(codecs_map_, codecs); | |
| 814 } | |
| 815 | |
| 816 void MimeUtil::ParseCodecString(const std::string& codecs, | |
| 817 std::vector<std::string>* codecs_out, | |
| 818 bool strip) { | |
| 819 std::string no_quote_codecs; | |
| 820 base::TrimString(codecs, "\"", &no_quote_codecs); | |
| 821 base::SplitString(no_quote_codecs, ',', codecs_out); | |
| 822 | |
| 823 if (!strip) | |
| 824 return; | |
| 825 | |
| 826 // Strip everything past the first '.' | |
| 827 for (std::vector<std::string>::iterator it = codecs_out->begin(); | |
| 828 it != codecs_out->end(); | |
| 829 ++it) { | |
| 830 size_t found = it->find_first_of('.'); | |
| 831 if (found != std::string::npos) | |
| 832 it->resize(found); | |
| 833 } | |
| 834 } | |
| 835 | |
| 836 bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { | |
| 837 if (strict_format_map_.find(mime_type) == strict_format_map_.end() && | |
| 838 strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end()) | |
| 839 return false; | |
| 840 return true; | |
| 841 } | |
| 842 | |
| 843 SupportsType MimeUtil::IsSupportedStrictMediaMimeType( | |
| 844 const std::string& mime_type, | |
| 845 const std::vector<std::string>& codecs) const { | |
| 846 StrictMappings::const_iterator it_strict_map = | |
| 847 strict_format_map_.find(mime_type); | |
| 848 if ((it_strict_map != strict_format_map_.end()) && | |
| 849 AreSupportedCodecs(it_strict_map->second, codecs)) { | |
| 850 return IsSupported; | |
| 851 } | |
| 852 | |
| 853 StrictExpressionMappings::const_iterator it_expression_map = | |
| 854 strict_mp4_format_map_.find(mime_type); | |
| 855 if ((it_expression_map != strict_mp4_format_map_.end()) && | |
| 856 AreSupportedCodecsWithProfile(it_expression_map->second, codecs)) { | |
| 857 return MayBeSupported; | |
| 858 } | |
| 859 | |
| 860 if (codecs.empty()) | |
| 861 return MayBeSupported; | |
| 862 | |
| 863 return IsNotSupported; | |
| 864 } | |
| 865 | |
| 866 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { | |
| 867 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) { | |
| 868 non_image_map_.erase(proprietary_media_types[i]); | |
| 869 media_map_.erase(proprietary_media_types[i]); | |
| 870 } | |
| 871 for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) | |
| 872 codecs_map_.erase(proprietary_media_codecs[i]); | |
| 873 } | |
| 874 | |
| 875 //---------------------------------------------------------------------------- | 495 //---------------------------------------------------------------------------- |
| 876 // Wrappers for the singleton | 496 // Wrappers for the singleton |
| 877 //---------------------------------------------------------------------------- | 497 //---------------------------------------------------------------------------- |
| 878 | 498 |
| 879 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, | 499 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, |
| 880 std::string* mime_type) { | 500 std::string* mime_type) { |
| 881 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type); | 501 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type); |
| 882 } | 502 } |
| 883 | 503 |
| 884 bool GetMimeTypeFromFile(const base::FilePath& file_path, | 504 bool GetMimeTypeFromFile(const base::FilePath& file_path, |
| 885 std::string* mime_type) { | 505 std::string* mime_type) { |
| 886 return g_mime_util.Get().GetMimeTypeFromFile(file_path, mime_type); | 506 return g_mime_util.Get().GetMimeTypeFromFile(file_path, mime_type); |
| 887 } | 507 } |
| 888 | 508 |
| 889 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext, | 509 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext, |
| 890 std::string* mime_type) { | 510 std::string* mime_type) { |
| 891 return g_mime_util.Get().GetWellKnownMimeTypeFromExtension(ext, mime_type); | 511 return g_mime_util.Get().GetWellKnownMimeTypeFromExtension(ext, mime_type); |
| 892 } | 512 } |
| 893 | 513 |
| 894 bool GetPreferredExtensionForMimeType(const std::string& mime_type, | 514 bool GetPreferredExtensionForMimeType(const std::string& mime_type, |
| 895 base::FilePath::StringType* extension) { | 515 base::FilePath::StringType* extension) { |
| 896 return g_mime_util.Get().GetPreferredExtensionForMimeType(mime_type, | 516 return g_mime_util.Get().GetPreferredExtensionForMimeType(mime_type, |
| 897 extension); | 517 extension); |
| 898 } | 518 } |
| 899 | 519 |
| 900 bool IsSupportedImageMimeType(const std::string& mime_type) { | 520 bool IsSupportedImageMimeType(const std::string& mime_type) { |
| 901 return g_mime_util.Get().IsSupportedImageMimeType(mime_type); | 521 return g_mime_util.Get().IsSupportedImageMimeType(mime_type); |
| 902 } | 522 } |
| 903 | 523 |
| 904 bool IsSupportedMediaMimeType(const std::string& mime_type) { | |
| 905 return g_mime_util.Get().IsSupportedMediaMimeType(mime_type); | |
| 906 } | |
| 907 | |
| 908 bool IsSupportedNonImageMimeType(const std::string& mime_type) { | 524 bool IsSupportedNonImageMimeType(const std::string& mime_type) { |
| 909 return g_mime_util.Get().IsSupportedNonImageMimeType(mime_type); | 525 return g_mime_util.Get().IsSupportedNonImageMimeType(mime_type); |
| 910 } | 526 } |
| 911 | 527 |
| 912 bool IsUnsupportedTextMimeType(const std::string& mime_type) { | 528 bool IsUnsupportedTextMimeType(const std::string& mime_type) { |
| 913 return g_mime_util.Get().IsUnsupportedTextMimeType(mime_type); | 529 return g_mime_util.Get().IsUnsupportedTextMimeType(mime_type); |
| 914 } | 530 } |
| 915 | 531 |
| 916 bool IsSupportedJavascriptMimeType(const std::string& mime_type) { | 532 bool IsSupportedJavascriptMimeType(const std::string& mime_type) { |
| 917 return g_mime_util.Get().IsSupportedJavascriptMimeType(mime_type); | 533 return g_mime_util.Get().IsSupportedJavascriptMimeType(mime_type); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 930 std::string* top_level_type, | 546 std::string* top_level_type, |
| 931 std::string* subtype) { | 547 std::string* subtype) { |
| 932 return g_mime_util.Get().ParseMimeTypeWithoutParameter( | 548 return g_mime_util.Get().ParseMimeTypeWithoutParameter( |
| 933 type_string, top_level_type, subtype); | 549 type_string, top_level_type, subtype); |
| 934 } | 550 } |
| 935 | 551 |
| 936 bool IsValidTopLevelMimeType(const std::string& type_string) { | 552 bool IsValidTopLevelMimeType(const std::string& type_string) { |
| 937 return g_mime_util.Get().IsValidTopLevelMimeType(type_string); | 553 return g_mime_util.Get().IsValidTopLevelMimeType(type_string); |
| 938 } | 554 } |
| 939 | 555 |
| 940 bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) { | |
| 941 return g_mime_util.Get().AreSupportedMediaCodecs(codecs); | |
| 942 } | |
| 943 | |
| 944 bool IsStrictMediaMimeType(const std::string& mime_type) { | |
| 945 return g_mime_util.Get().IsStrictMediaMimeType(mime_type); | |
| 946 } | |
| 947 | |
| 948 SupportsType IsSupportedStrictMediaMimeType( | |
| 949 const std::string& mime_type, | |
| 950 const std::vector<std::string>& codecs) { | |
| 951 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); | |
| 952 } | |
| 953 | |
| 954 void ParseCodecString(const std::string& codecs, | |
| 955 std::vector<std::string>* codecs_out, | |
| 956 const bool strip) { | |
| 957 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); | |
| 958 } | |
| 959 | |
| 960 namespace { | 556 namespace { |
| 961 | 557 |
| 962 // From http://www.w3schools.com/media/media_mimeref.asp and | 558 // From http://www.w3schools.com/media/media_mimeref.asp and |
| 963 // http://plugindoc.mozdev.org/winmime.php | 559 // http://plugindoc.mozdev.org/winmime.php |
| 964 static const char* const kStandardImageTypes[] = { | 560 static const char* const kStandardImageTypes[] = { |
| 965 "image/bmp", | 561 "image/bmp", |
| 966 "image/cis-cod", | 562 "image/cis-cod", |
| 967 "image/gif", | 563 "image/gif", |
| 968 "image/ief", | 564 "image/ief", |
| 969 "image/jpeg", | 565 "image/jpeg", |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 | 728 |
| 1133 GetExtensionsFromHardCodedMappings(secondary_mappings, | 729 GetExtensionsFromHardCodedMappings(secondary_mappings, |
| 1134 arraysize(secondary_mappings), | 730 arraysize(secondary_mappings), |
| 1135 mime_type, | 731 mime_type, |
| 1136 &unique_extensions); | 732 &unique_extensions); |
| 1137 } | 733 } |
| 1138 | 734 |
| 1139 HashSetToVector(&unique_extensions, extensions); | 735 HashSetToVector(&unique_extensions, extensions); |
| 1140 } | 736 } |
| 1141 | 737 |
| 1142 void RemoveProprietaryMediaTypesAndCodecsForTests() { | |
| 1143 g_mime_util.Get().RemoveProprietaryMediaTypesAndCodecsForTests(); | |
| 1144 } | |
| 1145 | |
| 1146 const std::string GetIANAMediaType(const std::string& mime_type) { | 738 const std::string GetIANAMediaType(const std::string& mime_type) { |
| 1147 for (size_t i = 0; i < arraysize(kIanaMediaTypes); ++i) { | 739 for (size_t i = 0; i < arraysize(kIanaMediaTypes); ++i) { |
| 1148 if (StartsWithASCII(mime_type, kIanaMediaTypes[i].matcher, true)) { | 740 if (StartsWithASCII(mime_type, kIanaMediaTypes[i].matcher, true)) { |
| 1149 return kIanaMediaTypes[i].name; | 741 return kIanaMediaTypes[i].name; |
| 1150 } | 742 } |
| 1151 } | 743 } |
| 1152 return std::string(); | 744 return std::string(); |
| 1153 } | 745 } |
| 1154 | 746 |
| 1155 CertificateMimeType GetCertificateMimeTypeForMimeType( | 747 CertificateMimeType GetCertificateMimeTypeForMimeType( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 post_data->append("\r\n" + value + "\r\n"); | 780 post_data->append("\r\n" + value + "\r\n"); |
| 1189 } | 781 } |
| 1190 | 782 |
| 1191 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, | 783 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, |
| 1192 std::string* post_data) { | 784 std::string* post_data) { |
| 1193 DCHECK(post_data); | 785 DCHECK(post_data); |
| 1194 post_data->append("--" + mime_boundary + "--\r\n"); | 786 post_data->append("--" + mime_boundary + "--\r\n"); |
| 1195 } | 787 } |
| 1196 | 788 |
| 1197 } // namespace net | 789 } // namespace net |
| OLD | NEW |