15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iterator>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/stl_util.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/base/mime_util.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/base/platform_mime_util.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/android/build_info.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MediaType {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char name[12];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char matcher[13];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const MediaType kIanaMediaTypes[] = {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application", "application/" },
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio", "audio/" },
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "example", "example/" },
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image", "image/" },
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "message", "message/" },
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "model", "model/" },
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "multipart", "multipart/" },
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "text", "text/" },
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "video", "video/" },
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Singleton utility class for mime types.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MimeUtil : public PlatformMimeUtil {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  enum Codec {
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    INVALID_CODEC,
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PCM,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MP3,
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MPEG2_AAC_LC,
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MPEG2_AAC_MAIN,
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MPEG2_AAC_SSR,
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MPEG4_AAC_LC,
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MPEG4_AAC_SBRv1,
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    VORBIS,
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    OPUS,
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    H264_BASELINE,
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    H264_MAIN,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    H264_HIGH,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    VP8,
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    VP9,
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    THEORA
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::string* mime_type) const;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool GetMimeTypeFromFile(const base::FilePath& file_path,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           std::string* mime_type) const;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         std::string* mime_type) const;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSupportedImageMimeType(const std::string& mime_type) const;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSupportedMediaMimeType(const std::string& mime_type) const;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSupportedNonImageMimeType(const std::string& mime_type) const;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsUnsupportedTextMimeType(const std::string& mime_type) const;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSupportedJavascriptMimeType(const std::string& mime_type) const;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSupportedMimeType(const std::string& mime_type) const;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool MatchesMimeType(const std::string &mime_type_pattern,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string &mime_type) const;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool ParseMimeTypeWithoutParameter(const std::string& type_string,
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     std::string* top_level_type,
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     std::string* subtype) const;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsValidTopLevelMimeType(const std::string& type_string) const;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) const;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ParseCodecString(const std::string& codecs,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::vector<std::string>* codecs_out,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bool strip);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsStrictMediaMimeType(const std::string& mime_type) const;
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupportsType IsSupportedStrictMediaMimeType(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& mime_type,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<std::string>& codecs) const;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void RemoveProprietaryMediaTypesAndCodecsForTests();
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct base::DefaultLazyInstanceTraits<MimeUtil>;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::hash_set<std::string> MimeMappings;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef base::hash_set<int> CodecSet;
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef std::map<std::string, CodecSet> StrictMappings;
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  struct CodecEntry {
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CodecEntry() : codec(INVALID_CODEC), is_ambiguous(true) {}
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CodecEntry(Codec c, bool ambiguous) : codec(c), is_ambiguous(ambiguous) {}
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Codec codec;
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_ambiguous;
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef std::map<std::string, CodecEntry> StringToCodecMappings;
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeUtil();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns IsSupported if all codec IDs in |codecs| are unambiguous
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and are supported by the platform. MayBeSupported is returned if
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // at least one codec ID in |codecs| is ambiguous but all the codecs
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // are supported by the platform. IsNotSupported is returned if at
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // least one codec ID  is not supported by the platform.
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SupportsType AreSupportedCodecs(
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const CodecSet& supported_codecs,
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::vector<std::string>& codecs) const;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For faster lookup, keep hash sets.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeMimeTypeMaps();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool include_platform_types,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* mime_type) const;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Converts a codec ID into an Codec enum value and indicates
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // whether the conversion was ambiguous.
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true if this method was able to map |codec_id| to a specific
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Codec enum value. |codec| and |is_ambiguous| are only valid if true
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // is returned. Otherwise their value is undefined after the call.
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |is_ambiguous| is true if |codec_id| did not have enough information to
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // unambiguously determine the proper Codec enum value. If |is_ambiguous|
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // is true |codec| contains the best guess for the intended Codec enum value.
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool StringToCodec(const std::string& codec_id,
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     Codec* codec,
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     bool* is_ambiguous) const;
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true if |codec| is supported by the platform.
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Note: This method will return false if the platform supports proprietary
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // codecs but |allow_proprietary_codecs_| is set to false.
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool IsCodecSupported(Codec codec) const;
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true if |codec| refers to a proprietary codec.
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool IsCodecProprietary(Codec codec) const;
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true and sets |*default_codec| if |mime_type| has a
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // default codec associated with it.
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns false otherwise and the value of |*default_codec| is undefined.
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool GetDefaultCodec(const std::string& mime_type,
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       Codec* default_codec) const;
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true if |mime_type| has a default codec associated with it
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // and IsCodecSupported() returns true for that particular codec.
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool IsDefaultCodecSupported(const std::string& mime_type) const;
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeMappings image_map_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeMappings media_map_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeMappings non_image_map_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeMappings unsupported_text_map_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MimeMappings javascript_map_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A map of mime_types and hash map of the supported codecs for the mime_type.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StrictMappings strict_format_map_;
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Keeps track of whether proprietary codec support should be
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // advertised to callers.
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool allow_proprietary_codecs_;
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Lookup table for string compare based string -> Codec mappings.
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StringToCodecMappings string_to_codec_map_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};  // class MimeUtil
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This variable is Leaky because we need to access it from WorkerPool threads.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MimeInfo {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* mime_type;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* extensions;  // comma separated list
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const MimeInfo primary_mappings[] = {
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  { "text/html", "html,htm,shtml,shtm" },
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "text/css", "css" },
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "text/xml", "xml" },
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/gif", "gif" },
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/jpeg", "jpeg,jpg" },
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/webp", "webp" },
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/png", "png" },
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "video/mp4", "mp4,m4v" },
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio/x-m4a", "m4a" },
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio/mp3", "mp3" },
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "video/ogg", "ogv,ogm" },
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "audio/ogg", "ogg,oga,opus" },
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "video/webm", "webm" },
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio/webm", "webm" },
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio/wav", "wav" },
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { "application/xhtml+xml", "xhtml,xht,xhtm" },
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/x-chrome-extension", "crx" },
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "multipart/related", "mhtml,mht" }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const MimeInfo secondary_mappings[] = {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/octet-stream", "exe,com,bin" },
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/gzip", "gz" },
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/pdf", "pdf" },
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/postscript", "ps,eps,ai" },
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  { "application/javascript", "js" },
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  { "application/font-woff", "woff" },
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/bmp", "bmp" },
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/x-icon", "ico" },
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "image/vnd.microsoft.icon", "ico" },
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/jpeg", "jfif,pjpeg,pjp" },
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/tiff", "tiff,tif" },
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/x-xbitmap", "xbm" },
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/svg+xml", "svg,svgz" },
236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  { "image/x-png", "png"},
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "message/rfc822", "eml" },
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "text/plain", "txt,text" },
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  { "text/html", "ehtml" },
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/rss+xml", "rss" },
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/rdf+xml", "rdf" },
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  { "text/xml", "xsl,xbl,xslt" },
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/vnd.mozilla.xul+xml", "xul" },
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/x-shockwave-flash", "swf,swl" },
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "application/pkcs7-mime", "p7m,p7c,p7z" },
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  { "application/pkcs7-signature", "p7s" },
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  { "application/x-mpegurl", "m3u8" },
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* FindMimeType(const MimeInfo* mappings,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                size_t mappings_len,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const char* ext) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t ext_len = strlen(ext);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < mappings_len; ++i) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* extensions = mappings[i].extensions;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (;;) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t end_pos = strcspn(extensions, ",");
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (end_pos == ext_len &&
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::strncasecmp(extensions, ext, ext_len) == 0)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mappings[i].mime_type;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions += end_pos;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!*extensions)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions += 1;  // skip over comma
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MimeUtil::GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        string* result) const {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMimeTypeFromExtensionHelper(ext, true, result);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::GetWellKnownMimeTypeFromExtension(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::StringType& ext,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string* result) const {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMimeTypeFromExtensionHelper(ext, false, result);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MimeUtil::GetMimeTypeFromFile(const base::FilePath& file_path,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   string* result) const {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType file_name_str = file_path.Extension();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_name_str.empty())
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMimeTypeFromExtension(file_name_str.substr(1), result);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MimeUtil::GetMimeTypeFromExtensionHelper(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::StringType& ext,
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool include_platform_types,
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string* result) const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoids crash when unable to handle a long file path. See crbug.com/48733.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned kMaxFilePathSize = 65536;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ext.length() > kMaxFilePathSize)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We implement the same algorithm as Mozilla for mapping a file extension to
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a mime type.  That is, we first check a hard-coded list (that cannot be
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overridden), and then if not found there, we defer to the system registry.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, we scan a secondary hard-coded list to catch types that we can
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deduce but that we also want to allow the OS to override.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FilePath path_ext(ext);
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const string ext_narrow_str = path_ext.AsUTF8Unsafe();
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const char* mime_type = FindMimeType(primary_mappings,
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                       arraysize(primary_mappings),
30968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                       ext_narrow_str.c_str());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mime_type) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = mime_type;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (include_platform_types && GetPlatformMimeTypeFromExtension(ext, result))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mime_type = FindMimeType(secondary_mappings, arraysize(secondary_mappings),
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ext_narrow_str.c_str());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mime_type) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = mime_type;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// From WebKit's WebCore/platform/MIMETypeRegistry.cpp:
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const supported_image_types[] = {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/jpeg",
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/pjpeg",
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/jpg",
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/webp",
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/png",
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/gif",
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/bmp",
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  "image/vnd.microsoft.icon",    // ico
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-icon",    // ico
340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  "image/x-xbitmap",  // xbm
341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  "image/x-png"
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A list of media types: http://en.wikipedia.org/wiki/Internet_media_type
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A comprehensive mime type list: http://plugindoc.mozdev.org/winmime.php
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This set of codecs is supported by all variations of Chromium.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const common_media_types[] = {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ogg.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/ogg",
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/ogg",
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if !defined(OS_ANDROID)  // Android doesn't support Ogg Theora.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/ogg",
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebM.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/webm",
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/webm",
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wav.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/wav",
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/x-wav",
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // HLS. Supported by Android ICS and above.
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  "application/vnd.apple.mpegurl",
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  "application/x-mpegurl",
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// List of proprietary types only supported by Google Chrome.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const proprietary_media_types[] = {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MPEG-4.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/mp4",
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-m4v",
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mp4",
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/x-m4a",
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MP3.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mp3",
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/x-mp3",
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mpeg",
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MPEG-2 TS.
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  "video/mp2t",
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Note:
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// - does not include javascript types list (see supported_javascript_types)
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// - does not include types starting with "text/" (see
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//   IsSupportedNonImageMimeType())
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const supported_non_image_types[] = {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/svg+xml",  // SVG is text-based XML, even though it has an image/ type
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/xml",
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/atom+xml",
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/rss+xml",
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/xhtml+xml",
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/json",
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "multipart/related",  // For MHTML support.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "multipart/x-mixed-replace"
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: ADDING a new type here will probably render it AS HTML. This can
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // result in cross site scripting.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Dictionary of cryptographic file mime types.
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct CertificateMimeTypeInfo {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* mime_type;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertificateMimeType cert_type;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const CertificateMimeTypeInfo supported_certificate_types[] = {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "application/x-x509-user-cert",
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CERTIFICATE_MIME_TYPE_X509_USER_CERT },
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "application/x-x509-ca-cert", CERTIFICATE_MIME_TYPE_X509_CA_CERT },
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "application/x-pkcs12", CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE },
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These types are excluded from the logic that allows all text/ types because
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while they are technically text, it's very unlikely that a user expects to
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// see them rendered in text form.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const unsupported_text_types[] = {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/calendar",
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-calendar",
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-vcalendar",
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/vcalendar",
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/vcard",
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-vcard",
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/directory",
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/ldif",
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/qif",
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-qif",
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-csv",
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/x-vcf",
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/rtf",
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/comma-separated-values",
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/csv",
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/tab-separated-values",
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/tsv",
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  "text/ofx",                           // http://crbug.com/162238
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  "text/vnd.sun.j2me.app-descriptor"    // http://crbug.com/176450
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Mozilla 1.8 and WinIE 7 both accept text/javascript and text/ecmascript.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Mozilla 1.8 accepts application/javascript, application/ecmascript, and
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// application/x-javascript, but WinIE 7 doesn't.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  WinIE 7 accepts text/javascript1.1 - text/javascript1.3, text/jscript, and
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// text/livescript, but Mozilla 1.8 doesn't.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Mozilla 1.8 allows leading and trailing whitespace, but WinIE 7 doesn't.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Mozilla 1.8 and WinIE 7 both accept the empty string, but neither accept a
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whitespace-only string.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  We want to accept all the values that either of these browsers accept, but
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not other values.
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const supported_javascript_types[] = {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/javascript",
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/ecmascript",
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/javascript",
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/ecmascript",
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "application/x-javascript",
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/javascript1.1",
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/javascript1.2",
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/javascript1.3",
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/jscript",
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "text/livescript"
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static bool IsCodecSupportedOnAndroid(MimeUtil::Codec codec) {
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (codec) {
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::INVALID_CODEC:
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::PCM:
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MP3:
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MPEG4_AAC_LC:
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MPEG4_AAC_SBRv1:
4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::H264_BASELINE:
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case MimeUtil::H264_MAIN:
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case MimeUtil::H264_HIGH:
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::VP8:
4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::VORBIS:
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MPEG2_AAC_LC:
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MPEG2_AAC_MAIN:
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::MPEG2_AAC_SSR:
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // MPEG-2 variants of AAC are not supported on Android.
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::VP9:
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // VP9 is supported only in KitKat+ (API Level 19).
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::OPUS:
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // TODO(vigneshv): Change this similar to the VP9 check once Opus is
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // supported on Android (http://crbug.com/318436).
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MimeUtil::THEORA:
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static bool IsMimeTypeSupportedOnAndroid(const std::string& mimeType) {
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // HLS codecs are supported in ICS and above (API level 14)
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if ((!mimeType.compare("application/vnd.apple.mpegurl") ||
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !mimeType.compare("application/x-mpegurl")) &&
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::android::BuildInfo::GetInstance()->sdk_int() < 14) {
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MediaFormatStrict {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* mime_type;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* codecs_list;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Following is the list of RFC 6381 compliant codecs:
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.66     - MPEG-2 AAC MAIN
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.67     - MPEG-2 AAC LC
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.68     - MPEG-2 AAC SSR
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.69     - MPEG-2 extension to MPEG-1
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.6B     - MPEG-1 audio
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.40.2   - MPEG-4 AAC LC
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   mp4a.40.5   - MPEG-4 AAC SBRv1
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   avc1.42E0xx - H.264 Baseline
5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   avc1.4D40xx - H.264 Main
5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   avc1.6400xx - H.264 High
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const char kMP4AudioCodecsExpression[] =
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5";
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const char kMP4VideoCodecsExpression[] =
5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "avc1.42E00A,avc1.4D400A,avc1.64000A," \
5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5";
5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const MediaFormatStrict format_codec_mappings[] = {
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { "video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0" },
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { "audio/webm", "opus,vorbis" },
545c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { "audio/wav", "1" },
546c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { "audio/x-wav", "1" },
547c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { "video/ogg", "opus,theora,vorbis" },
548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  { "audio/ogg", "opus,vorbis" },
5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  { "application/ogg", "opus,theora,vorbis" },
5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "audio/mpeg", "mp3" },
5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  { "audio/mp3", "" },
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "audio/x-mp3", "" },
5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "audio/mp4", kMP4AudioCodecsExpression },
5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "audio/x-m4a", kMP4AudioCodecsExpression },
5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "video/mp4", kMP4VideoCodecsExpression },
5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "video/x-m4v", kMP4VideoCodecsExpression },
5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "application/x-mpegurl", kMP4VideoCodecsExpression },
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "application/vnd.apple.mpegurl", kMP4VideoCodecsExpression }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct CodecIDMappings {
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char* const codec_id;
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MimeUtil::Codec codec;
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// List of codec IDs that provide enough information to determine the
5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// codec and profile being requested.
568f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The "mp4a" strings come from RFC 6381.
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const CodecIDMappings kUnambiguousCodecIDs[] = {
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "1", MimeUtil::PCM }, // We only allow this for WAV so it isn't ambiguous.
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp3", MimeUtil::MP3 },
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.66", MimeUtil::MPEG2_AAC_MAIN },
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.67", MimeUtil::MPEG2_AAC_LC },
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.68", MimeUtil::MPEG2_AAC_SSR },
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.69", MimeUtil::MP3 },
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.6B", MimeUtil::MP3 },
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.40.2", MimeUtil::MPEG4_AAC_LC },
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.40.5", MimeUtil::MPEG4_AAC_SBRv1 },
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "vorbis", MimeUtil::VORBIS },
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "opus", MimeUtil::OPUS },
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "vp8", MimeUtil::VP8 },
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "vp8.0", MimeUtil::VP8 },
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "vp9", MimeUtil::VP9 },
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "vp9.0", MimeUtil::VP9 },
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "theora", MimeUtil::THEORA }
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// List of codec IDs that are ambiguous and don't provide
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// enough information to determine the codec and profile.
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The codec in these entries indicate the codec and profile
5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// we assume the user is trying to indicate.
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const CodecIDMappings kAmbiguousCodecIDs[] = {
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "mp4a.40", MimeUtil::MPEG4_AAC_LC },
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "avc1", MimeUtil::H264_BASELINE },
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  { "avc3", MimeUtil::H264_BASELINE },
597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeMimeTypeMaps();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupportsType MimeUtil::AreSupportedCodecs(
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const CodecSet& supported_codecs,
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::vector<std::string>& codecs) const {
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!supported_codecs.empty());
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!codecs.empty());
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SupportsType result = IsSupported;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < codecs.size(); ++i) {
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_ambiguous = true;
6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Codec codec = INVALID_CODEC;
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!StringToCodec(codecs[i], &codec, &is_ambiguous))
6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return IsNotSupported;
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!IsCodecSupported(codec) ||
6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        supported_codecs.find(codec) == supported_codecs.end()) {
6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return IsNotSupported;
619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (is_ambiguous)
6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      result = MayBeSupported;
623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return result;
626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MimeUtil::InitializeMimeTypeMaps() {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_image_types); ++i)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_map_.insert(supported_image_types[i]);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the supported non-image types.
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_non_image_types); ++i)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    non_image_map_.insert(supported_non_image_types[i]);
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_certificate_types); ++i)
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    non_image_map_.insert(supported_certificate_types[i].mime_type);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(unsupported_text_types); ++i)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsupported_text_map_.insert(unsupported_text_types[i]);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_javascript_types); ++i)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    non_image_map_.insert(supported_javascript_types[i]);
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < arraysize(common_media_types); ++i) {
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_ANDROID)
643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!IsMimeTypeSupportedOnAndroid(common_media_types[i]))
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    non_image_map_.insert(common_media_types[i]);
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  allow_proprietary_codecs_ = true;
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(proprietary_media_types); ++i)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    non_image_map_.insert(proprietary_media_types[i]);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the supported media types.
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < arraysize(common_media_types); ++i) {
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_ANDROID)
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!IsMimeTypeSupportedOnAndroid(common_media_types[i]))
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media_map_.insert(common_media_types[i]);
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(proprietary_media_types); ++i)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media_map_.insert(proprietary_media_types[i]);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_javascript_types); ++i)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    javascript_map_.insert(supported_javascript_types[i]);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kUnambiguousCodecIDs); ++i) {
6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    string_to_codec_map_[kUnambiguousCodecIDs[i].codec_id] =
6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        CodecEntry(kUnambiguousCodecIDs[i].codec, false);
6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kAmbiguousCodecIDs); ++i) {
6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    string_to_codec_map_[kAmbiguousCodecIDs[i].codec_id] =
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        CodecEntry(kAmbiguousCodecIDs[i].codec, true);
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the strict supported media types.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> mime_type_codecs;
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ParseCodecString(format_codec_mappings[i].codecs_list,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     &mime_type_codecs,
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     false);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CodecSet codecs;
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Codec codec = INVALID_CODEC;
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bool is_ambiguous = true;
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous));
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK(!is_ambiguous);
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      codecs.insert(codec);
695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
698f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return image_map_.find(mime_type) != image_map_.end();
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return media_map_.find(mime_type) != media_map_.end();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsSupportedNonImageMimeType(const std::string& mime_type) const {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return non_image_map_.find(mime_type) != non_image_map_.end() ||
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (mime_type.compare(0, 5, "text/") == 0 &&
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !IsUnsupportedTextMimeType(mime_type)) ||
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (mime_type.compare(0, 12, "application/") == 0 &&
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       MatchesMimeType("application/*+json", mime_type));
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsUnsupportedTextMimeType(const std::string& mime_type) const {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return unsupported_text_map_.find(mime_type) != unsupported_text_map_.end();
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsSupportedJavascriptMimeType(
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& mime_type) const {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return javascript_map_.find(mime_type) != javascript_map_.end();
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mirrors WebViewImpl::CanShowMIMEType()
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (mime_type.compare(0, 6, "image/") == 0 &&
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IsSupportedImageMimeType(mime_type)) ||
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         IsSupportedNonImageMimeType(mime_type);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests for MIME parameter equality. Each parameter in the |mime_type_pattern|
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// must be matched by a parameter in the |mime_type|. If there are no
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters in the pattern, the match is a success.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MatchesMimeTypeParameters(const std::string& mime_type_pattern,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& mime_type) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string::size_type semicolon = mime_type_pattern.find(';');
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string::size_type test_semicolon = mime_type.find(';');
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (semicolon != std::string::npos) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_semicolon == std::string::npos)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> pattern_parameters;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SplitString(mime_type_pattern.substr(semicolon + 1),
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      ';', &pattern_parameters);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> test_parameters;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SplitString(mime_type.substr(test_semicolon + 1),
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      ';', &test_parameters);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sort(pattern_parameters.begin(), pattern_parameters.end());
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sort(test_parameters.begin(), test_parameters.end());
75468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::vector<std::string> difference =
75568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::STLSetDifference<std::vector<std::string> >(pattern_parameters,
75668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                        test_parameters);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return difference.size() == 0;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This comparison handles absolute maching and also basic
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wildcards.  The plugin mime types could be:
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      application/x-foo
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      application/*
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      application/*+xml
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      *
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests mime parameters -- all parameters in the pattern must be present
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the tested type for a match to succeed.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::MatchesMimeType(const std::string& mime_type_pattern,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& mime_type) const {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify caller is passing lowercase strings.
7736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK_EQ(base::StringToLowerASCII(mime_type_pattern), mime_type_pattern);
7746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK_EQ(base::StringToLowerASCII(mime_type), mime_type);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mime_type_pattern.empty())
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string::size_type semicolon = mime_type_pattern.find(';');
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string base_pattern(mime_type_pattern.substr(0, semicolon));
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  semicolon = mime_type.find(';');
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string base_type(mime_type.substr(0, semicolon));
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base_pattern == "*" || base_pattern == "*/*")
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string::size_type star = base_pattern.find('*');
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (star == std::string::npos) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base_pattern == base_type)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test length to prevent overlap between |left| and |right|.
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base_type.length() < base_pattern.length() - 1)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string left(base_pattern.substr(0, star));
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string right(base_pattern.substr(star + 1));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base_type.find(left) != 0)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!right.empty() &&
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_type.rfind(right) != base_type.length() - right.length())
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See http://www.iana.org/assignments/media-types/media-types.xhtml
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* legal_top_level_types[] = {
814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "application",
815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "audio",
816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "example",
817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "image",
818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "message",
819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "model",
820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "multipart",
821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "text",
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  "video",
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MimeUtil::ParseMimeTypeWithoutParameter(
826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& type_string,
827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string* top_level_type,
828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string* subtype) const {
829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> components;
830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::SplitString(type_string, '/', &components);
831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (components.size() != 2 ||
832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !HttpUtil::IsToken(components[0]) ||
833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !HttpUtil::IsToken(components[1]))
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (top_level_type)
837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *top_level_type = components[0];
838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (subtype)
839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *subtype = components[1];
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const {
8446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string lower_type = base::StringToLowerASCII(type_string);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(legal_top_level_types); ++i) {
846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (lower_type.compare(legal_top_level_types[i]) == 0)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return type_string.size() > 2 && StartsWithASCII(type_string, "x-", false);
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::AreSupportedMediaCodecs(
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<std::string>& codecs) const {
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < codecs.size(); ++i) {
8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Codec codec = INVALID_CODEC;
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_ambiguous = true;
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!StringToCodec(codecs[i], &codec, &is_ambiguous) ||
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !IsCodecSupported(codec)) {
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MimeUtil::ParseCodecString(const std::string& codecs,
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                std::vector<std::string>* codecs_out,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool strip) {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string no_quote_codecs;
870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TrimString(codecs, "\"", &no_quote_codecs);
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(no_quote_codecs, ',', codecs_out);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!strip)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Strip everything past the first '.'
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<std::string>::iterator it = codecs_out->begin();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != codecs_out->end();
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t found = it->find_first_of('.');
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (found != std::string::npos)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it->resize(found);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
8875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return strict_format_map_.find(mime_type) != strict_format_map_.end();
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
890f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& mime_type,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<std::string>& codecs) const {
893f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  StrictMappings::const_iterator it_strict_map =
894f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      strict_format_map_.find(mime_type);
8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (it_strict_map == strict_format_map_.end())
8965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return codecs.empty() ? MayBeSupported : IsNotSupported;
897f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (it_strict_map->second.empty()) {
8995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // We get here if the mimetype does not expect a codecs parameter.
9005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return (codecs.empty() && IsDefaultCodecSupported(mime_type)) ?
9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        IsSupported : IsNotSupported;
902f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
903f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (codecs.empty()) {
9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // We get here if the mimetype expects to get a codecs parameter,
9065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // but didn't get one. If |mime_type| does not have a default codec
9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // the best we can do is say "maybe" because we don't have enough
9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // information.
9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Codec default_codec = INVALID_CODEC;
9105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!GetDefaultCodec(mime_type, &default_codec))
9115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return MayBeSupported;
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported;
9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
915f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return AreSupportedCodecs(it_strict_map->second, codecs);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) {
921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    non_image_map_.erase(proprietary_media_types[i]);
922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    media_map_.erase(proprietary_media_types[i]);
923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  allow_proprietary_codecs_ = false;
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
92734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// Returns true iff |profile_str| conforms to hex string "42y0", where y is one
92834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// of [8..F]. Requiring constraint_set0_flag be set and profile_idc be 0x42 is
92934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// taken from ISO-14496-10 7.3.2.1, 7.4.2.1, and Annex A.2.1.
93034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//
93134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// |profile_str| is the first four characters of the H.264 suffix string
93234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// (ignoring the last 2 characters of the full 6 character suffix that are
93334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// level_idc). From ISO-14496-10 7.3.2.1, it consists of:
93434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 8 bits: profile_idc: required to be 0x42 here.
93534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 1 bit: constraint_set0_flag : required to be true here.
93634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 1 bit: constraint_set1_flag : ignored here.
93734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 1 bit: constraint_set2_flag : ignored here.
93834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 1 bit: constraint_set3_flag : ignored here.
93934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// 4 bits: reserved : required to be 0 here.
94034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//
94134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// The spec indicates other ways, not implemented here, that a |profile_str|
94234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// can indicate a baseline conforming decoder is sufficient for decode in Annex
94334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// A.2.1: "[profile_idc not necessarily 0x42] with constraint_set0_flag set and
94434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// in which level_idc and constraint_set3_flag represent a level less than or
94534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// equal to the specified level."
94634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)static bool IsValidH264BaselineProfile(const std::string& profile_str) {
94734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  uint32 constraint_set_bits;
94834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (profile_str.size() != 4 ||
94934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      profile_str[0] != '4' ||
95034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      profile_str[1] != '2' ||
95134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      profile_str[3] != '0' ||
95234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      !base::HexStringToUInt(base::StringPiece(profile_str.c_str() + 2, 1),
95334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                             &constraint_set_bits)) {
95434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return false;
95534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
95634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
95734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  return constraint_set_bits >= 8;
95834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
95934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static bool IsValidH264Level(const std::string& level_str) {
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uint32 level;
9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level))
9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Valid levels taken from Table A-1 in ISO-14496-10.
9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Essentially |level_str| is toHex(10 * level).
9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ((level >= 10 && level <= 13) ||
9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          (level >= 20 && level <= 22) ||
9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          (level >= 30 && level <= 32) ||
9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          (level >= 40 && level <= 42) ||
9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          (level >= 50 && level <= 51));
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
97434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)// Handle parsing H.264 codec IDs as outlined in RFC 6381 and ISO-14496-10.
97534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   avc1.42y0xx, y >= 8 - H.264 Baseline
97634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   avc1.4D40xx         - H.264 Main
97734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   avc1.6400xx         - H.264 High
9785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
97934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to
98034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   signal H.264 Baseline. For example, the idc_level, profile_idc and
98134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   constraint_set3_flag pieces may explicitly require decoder to conform to
98234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   baseline profile at the specified level (see Annex A and constraint_set0 in
98334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)//   ISO-14496-10).
9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static bool ParseH264CodecID(const std::string& codec_id,
9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             MimeUtil::Codec* codec,
9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             bool* is_ambiguous) {
9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Make sure we have avc1.xxxxxx or avc3.xxxxxx
9885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (codec_id.size() != 11 ||
9895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      (!StartsWithASCII(codec_id, "avc1.", true) &&
9905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       !StartsWithASCII(codec_id, "avc3.", true))) {
9915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string profile = StringToUpperASCII(codec_id.substr(5, 4));
99534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (IsValidH264BaselineProfile(profile)) {
9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *codec = MimeUtil::H264_BASELINE;
9975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (profile == "4D40") {
9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *codec = MimeUtil::H264_MAIN;
9995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (profile == "6400") {
10005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *codec = MimeUtil::H264_HIGH;
10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
10025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *codec = MimeUtil::H264_BASELINE;
10035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *is_ambiguous = true;
10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9)));
10085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
10095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MimeUtil::StringToCodec(const std::string& codec_id,
10125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             Codec* codec,
10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             bool* is_ambiguous) const {
10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StringToCodecMappings::const_iterator itr =
10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      string_to_codec_map_.find(codec_id);
10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (itr != string_to_codec_map_.end()) {
10175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *codec = itr->second.codec;
10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *is_ambiguous = itr->second.is_ambiguous;
10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // an H.264 codec ID because currently those are the only ones that can't be
10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // stored in the |string_to_codec_map_| and require parsing.
10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ParseH264CodecID(codec_id, codec, is_ambiguous);
10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MimeUtil::IsCodecSupported(Codec codec) const {
10295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_NE(codec, INVALID_CODEC);
10305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID)
10325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!IsCodecSupportedOnAndroid(codec))
10335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
10345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
10355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
10375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MimeUtil::IsCodecProprietary(Codec codec) const {
10405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (codec) {
10415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case INVALID_CODEC:
10425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MP3:
10435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MPEG2_AAC_LC:
10445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MPEG2_AAC_MAIN:
10455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MPEG2_AAC_SSR:
10465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MPEG4_AAC_LC:
10475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MPEG4_AAC_SBRv1:
10485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case H264_BASELINE:
10495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case H264_MAIN:
10505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case H264_HIGH:
10515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
10525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case PCM:
10545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case VORBIS:
10555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case OPUS:
10565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case VP8:
10575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case VP9:
10585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case THEORA:
10595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
10605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
10635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MimeUtil::GetDefaultCodec(const std::string& mime_type,
10665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               Codec* default_codec) const {
10675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (mime_type == "audio/mpeg" ||
10685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      mime_type == "audio/mp3" ||
10695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      mime_type == "audio/x-mp3") {
10705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *default_codec = MimeUtil::MP3;
10715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
10725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
10735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
10755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
10765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MimeUtil::IsDefaultCodecSupported(const std::string& mime_type) const {
10795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Codec default_codec = Codec::INVALID_CODEC;
10805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!GetDefaultCodec(mime_type, &default_codec))
10815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
10825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return IsCodecSupported(default_codec);
1083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wrappers for the singleton
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::string* mime_type) {
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetMimeTypeFromFile(const base::FilePath& file_path,
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         std::string* mime_type) {
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().GetMimeTypeFromFile(file_path, mime_type);
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext,
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::string* mime_type) {
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().GetWellKnownMimeTypeFromExtension(ext, mime_type);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetPreferredExtensionForMimeType(const std::string& mime_type,
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::FilePath::StringType* extension) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().GetPreferredExtensionForMimeType(mime_type,
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            extension);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSupportedImageMimeType(const std::string& mime_type) {
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedImageMimeType(mime_type);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSupportedMediaMimeType(const std::string& mime_type) {
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedMediaMimeType(mime_type);
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSupportedNonImageMimeType(const std::string& mime_type) {
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedNonImageMimeType(mime_type);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsUnsupportedTextMimeType(const std::string& mime_type) {
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsUnsupportedTextMimeType(mime_type);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSupportedJavascriptMimeType(const std::string& mime_type) {
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedJavascriptMimeType(mime_type);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSupportedMimeType(const std::string& mime_type) {
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedMimeType(mime_type);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MatchesMimeType(const std::string& mime_type_pattern,
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& mime_type) {
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().MatchesMimeType(mime_type_pattern, mime_type);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ParseMimeTypeWithoutParameter(const std::string& type_string,
1140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   std::string* top_level_type,
1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   std::string* subtype) {
1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return g_mime_util.Get().ParseMimeTypeWithoutParameter(
1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      type_string, top_level_type, subtype);
1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool IsValidTopLevelMimeType(const std::string& type_string) {
1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return g_mime_util.Get().IsValidTopLevelMimeType(type_string);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AreSupportedMediaCodecs(const std::vector<std::string>& codecs) {
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().AreSupportedMediaCodecs(codecs);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsStrictMediaMimeType(const std::string& mime_type) {
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsStrictMediaMimeType(mime_type);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupportsType IsSupportedStrictMediaMimeType(
1159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& mime_type,
1160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::vector<std::string>& codecs) {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParseCodecString(const std::string& codecs,
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      std::vector<std::string>* codecs_out,
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const bool strip) {
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip);
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// From http://www.w3schools.com/media/media_mimeref.asp and
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://plugindoc.mozdev.org/winmime.php
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const kStandardImageTypes[] = {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/bmp",
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/cis-cod",
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/gif",
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/ief",
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/jpeg",
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/webp",
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/pict",
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/pipeg",
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/png",
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/svg+xml",
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/tiff",
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  "image/vnd.microsoft.icon",
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-cmu-raster",
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-cmx",
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-icon",
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-portable-anymap",
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-portable-bitmap",
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-portable-graymap",
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-portable-pixmap",
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-rgb",
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-xbitmap",
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-xpixmap",
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "image/x-xwindowdump"
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const kStandardAudioTypes[] = {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/aac",
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/aiff",
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/amr",
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/basic",
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/midi",
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mp3",
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mp4",
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mpeg",
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/mpeg3",
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/ogg",
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/vorbis",
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/wav",
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/webm",
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/x-m4a",
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/x-ms-wma",
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/vnd.rn-realaudio",
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "audio/vnd.wave"
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* const kStandardVideoTypes[] = {
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/avi",
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/divx",
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/flc",
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/mp4",
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/mpeg",
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/ogg",
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/quicktime",
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/sd-video",
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/webm",
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-dv",
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-m4v",
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-mpeg",
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-ms-asf",
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "video/x-ms-wmv"
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct StandardType {
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* leading_mime_type;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const* standard_types;
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t standard_types_len;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const StandardType kStandardTypes[] = {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "image/", kStandardImageTypes, arraysize(kStandardImageTypes) },
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "audio/", kStandardAudioTypes, arraysize(kStandardAudioTypes) },
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "video/", kStandardVideoTypes, arraysize(kStandardVideoTypes) },
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { NULL, NULL, 0 }
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetExtensionsFromHardCodedMappings(
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MimeInfo* mappings,
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t mappings_len,
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& leading_mime_type,
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::hash_set<base::FilePath::StringType>* extensions) {
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType extension;
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < mappings_len; ++i) {
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (StartsWithASCII(mappings[i].mime_type, leading_mime_type, false)) {
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<string> this_extensions;
1256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::SplitString(mappings[i].extensions, ',', &this_extensions);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t j = 0; j < this_extensions.size(); ++j) {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
12595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::FilePath::StringType extension(
12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::UTF8ToWide(this_extensions[j]));
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::StringType extension(this_extensions[j]);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions->insert(extension);
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetExtensionsHelper(
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* const* standard_types,
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t standard_types_len,
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& leading_mime_type,
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::hash_set<base::FilePath::StringType>* extensions) {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < standard_types_len; ++i) {
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_mime_util.Get().GetPlatformExtensionsForMimeType(standard_types[i],
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       extensions);
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also look up the extensions from hard-coded mappings in case that some
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supported extensions are not registered in the system registry, like ogg.
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetExtensionsFromHardCodedMappings(primary_mappings,
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     arraysize(primary_mappings),
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     leading_mime_type,
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     extensions);
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetExtensionsFromHardCodedMappings(secondary_mappings,
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     arraysize(secondary_mappings),
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     leading_mime_type,
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     extensions);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the elements in the source set will be appended to the target
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// vector.
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T>
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) {
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t old_target_size = target->size();
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target->resize(old_target_size + source->size());
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t i = 0;
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (typename base::hash_set<T>::iterator iter = source->begin();
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != source->end(); ++iter, ++i)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*target)[old_target_size + i] = *iter;
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetExtensionsForMimeType(
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& unsafe_mime_type,
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<base::FilePath::StringType>* extensions) {
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (unsafe_mime_type == "*/*" || unsafe_mime_type == "*")
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const std::string mime_type = base::StringToLowerASCII(unsafe_mime_type);
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::hash_set<base::FilePath::StringType> unique_extensions;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (EndsWith(mime_type, "/*", true)) {
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string leading_mime_type = mime_type.substr(0, mime_type.length() - 1);
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Find the matching StandardType from within kStandardTypes, or fall
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // through to the last (default) StandardType.
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const StandardType* type = NULL;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kStandardTypes); ++i) {
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = &(kStandardTypes[i]);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (type->leading_mime_type &&
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          leading_mime_type == type->leading_mime_type)
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(type);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetExtensionsHelper(type->standard_types,
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        type->standard_types_len,
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        leading_mime_type,
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &unique_extensions);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_mime_util.Get().GetPlatformExtensionsForMimeType(mime_type,
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &unique_extensions);
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also look up the extensions from hard-coded mappings in case that some
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported extensions are not registered in the system registry, like ogg.
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetExtensionsFromHardCodedMappings(primary_mappings,
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       arraysize(primary_mappings),
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mime_type,
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &unique_extensions);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetExtensionsFromHardCodedMappings(secondary_mappings,
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       arraysize(secondary_mappings),
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mime_type,
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &unique_extensions);
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HashSetToVector(&unique_extensions, extensions);
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RemoveProprietaryMediaTypesAndCodecsForTests() {
1353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_mime_util.Get().RemoveProprietaryMediaTypesAndCodecsForTests();
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string GetIANAMediaType(const std::string& mime_type) {
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kIanaMediaTypes); ++i) {
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (StartsWithASCII(mime_type, kIanaMediaTypes[i].matcher, true)) {
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kIanaMediaTypes[i].name;
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::string();
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CertificateMimeType GetCertificateMimeTypeForMimeType(
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& mime_type) {
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't create a map, there is only one entry in the table,
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // except on Android.
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(supported_certificate_types); ++i) {
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mime_type == net::supported_certificate_types[i].mime_type)
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return net::supported_certificate_types[i].cert_type;
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CERTIFICATE_MIME_TYPE_UNKNOWN;
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsSupportedCertificateMimeType(const std::string& mime_type) {
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CertificateMimeType file_type =
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetCertificateMimeTypeForMimeType(mime_type);
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return file_type != CERTIFICATE_MIME_TYPE_UNKNOWN;
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AddMultipartValueForUpload(const std::string& value_name,
138390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const std::string& value,
138490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const std::string& mime_boundary,
138590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const std::string& content_type,
138690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                std::string* post_data) {
138790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(post_data);
138890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // First line is the boundary.
138990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  post_data->append("--" + mime_boundary + "\r\n");
139090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Next line is the Content-disposition.
139190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  post_data->append("Content-Disposition: form-data; name=\"" +
139290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    value_name + "\"\r\n");
139390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!content_type.empty()) {
139490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // If Content-type is specified, the next line is that.
139590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    post_data->append("Content-Type: " + content_type + "\r\n");
139690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
139790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Leave an empty line and append the value.
139890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  post_data->append("\r\n" + value + "\r\n");
139990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
140090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
140190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary,
140290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                         std::string* post_data) {
140390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(post_data);
140490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  post_data->append("--" + mime_boundary + "--\r\n");
140590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
140690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1408