summaryrefslogtreecommitdiffstats
path: root/net/base/mime_util.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 22:42:52 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 22:42:52 +0000
commit586acc5fe142f498261f52c66862fa417c3d52d2 (patch)
treec98b3417a883f2477029c8cd5888f4078681e24e /net/base/mime_util.cc
parenta814a8d55429605fe6d7045045cd25b6bf624580 (diff)
downloadchromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.zip
chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.gz
chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.bz2
Add net to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/mime_util.cc')
-rw-r--r--net/base/mime_util.cc305
1 files changed, 305 insertions, 0 deletions
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
new file mode 100644
index 0000000..71421f9
--- /dev/null
+++ b/net/base/mime_util.cc
@@ -0,0 +1,305 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <hash_set>
+#include <string.h>
+
+#include "net/base/mime_util.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/registry.h"
+#include "base/string_util.h"
+
+using std::string;
+using std::wstring;
+
+namespace mime_util {
+
+struct MimeInfo {
+ const char* mime_type;
+ const char* extensions; // comma separated list
+};
+
+static const MimeInfo primary_mappings[] = {
+ { "text/html", "html,htm" },
+ { "text/css", "css" },
+ { "text/xml", "xml" },
+ { "image/gif", "gif" },
+ { "image/jpeg", "jpeg,jpg" },
+ { "image/png", "png" },
+ { "application/xhtml+xml", "xhtml,xht" }
+};
+
+static const MimeInfo secondary_mappings[] = {
+ { "application/octet-stream", "exe,com,bin" },
+ { "application/gzip", "gz" },
+ { "application/pdf", "pdf" },
+ { "application/postscript", "ps,eps,ai" },
+ { "application/x-javascript", "js" },
+ { "image/bmp", "bmp" },
+ { "image/x-icon", "ico" },
+ { "image/jpeg", "jfif,pjpeg,pjp" },
+ { "image/tiff", "tiff,tif" },
+ { "image/x-xbitmap", "xbm" },
+ { "image/svg+xml", "svg,svgz" },
+ { "message/rfc822", "eml" },
+ { "text/plain", "txt,text" },
+ { "text/html", "shtml,ehtml" },
+ { "application/rss+xml", "rss" },
+ { "application/rdf+xml", "rdf" },
+ { "text/xml", "xsl,xbl" },
+ { "application/vnd.mozilla.xul+xml", "xul" },
+ { "application/x-shockwave-flash", "swf,swl" }
+};
+
+static const char* FindMimeType(const MimeInfo* mappings, size_t mappings_len,
+ const char* ext) {
+ size_t ext_len = strlen(ext);
+
+ for (size_t i = 0; i < mappings_len; ++i) {
+ const char* extensions = mappings[i].extensions;
+ for (;;) {
+ size_t end_pos = strcspn(extensions, ",");
+ if (end_pos == ext_len && _strnicmp(extensions, ext, ext_len) == 0)
+ return mappings[i].mime_type;
+ extensions += end_pos;
+ if (!*extensions)
+ break;
+ extensions += 1; // skip over comma
+ }
+ }
+ return NULL;
+}
+
+bool GetMimeTypeFromExtension(const wstring& ext, string* result) {
+ // We implement the same algorithm as Mozilla for mapping a file extension to
+ // a mime type. That is, we first check a hard-coded list (that cannot be
+ // overridden), and then if not found there, we defer to the system registry.
+ // Finally, we scan a secondary hard-coded list to catch types that we can
+ // deduce but that we also want to allow the OS to override.
+
+ string ext_utf8 = WideToUTF8(ext);
+ const char* mime_type;
+
+ mime_type = FindMimeType(primary_mappings, arraysize(primary_mappings),
+ ext_utf8.c_str());
+ if (mime_type) {
+ *result = mime_type;
+ return true;
+ }
+
+ // check windows registry for file extension's mime type (registry key
+ // names are not case-sensitive).
+ wstring value, key = L"." + ext;
+ RegKey(HKEY_CLASSES_ROOT, key.c_str()).ReadValue(L"Content Type", &value);
+ if (!value.empty()) {
+ *result = WideToUTF8(value);
+ return true;
+ }
+
+ mime_type = FindMimeType(secondary_mappings, arraysize(secondary_mappings),
+ ext_utf8.c_str());
+ if (mime_type) {
+ *result = mime_type;
+ return true;
+ }
+
+ return false;
+}
+
+bool GetMimeTypeFromFile(const wstring& file_path, string* result) {
+ wstring::size_type dot = file_path.find_last_of('.');
+ if (dot == wstring::npos)
+ return false;
+ return GetMimeTypeFromExtension(file_path.substr(dot + 1), result);
+}
+
+bool GetPreferredExtensionForMimeType(const std::string& mime_type,
+ std::wstring* ext) {
+ wstring key(L"MIME\\Database\\Content Type\\" + UTF8ToWide(mime_type));
+ return RegKey(HKEY_CLASSES_ROOT, key.c_str()).ReadValue(L"Extension", ext);
+}
+
+
+// From WebKit's WebCore/platform/MIMETypeRegistry.cpp:
+
+static const char* supported_image_types[] = {
+ "image/jpeg",
+ "image/jpg",
+ "image/png",
+ "image/gif",
+ "image/bmp",
+ "image/x-icon", // ico
+ "image/x-xbitmap" // xbm
+};
+
+// Note: does not include javascript types list (see supported_javascript_types)
+static const char* supported_non_image_types[] = {
+ "text/html",
+ "text/xml",
+ "text/xsl",
+ "text/plain",
+ "text/",
+ "image/svg+xml", // SVG is text-based XML, even though it has an image/ type
+ "application/xml",
+ "application/xhtml+xml",
+ "application/rss+xml",
+ "application/atom+xml",
+ "multipart/x-mixed-replace"
+};
+
+// Mozilla 1.8 and WinIE 7 both accept text/javascript and text/ecmascript.
+// Mozilla 1.8 accepts application/javascript, application/ecmascript, and application/x-javascript, but WinIE 7 doesn't.
+// WinIE 7 accepts text/javascript1.1 - text/javascript1.3, text/jscript, and text/livescript, but Mozilla 1.8 doesn't.
+// Mozilla 1.8 allows leading and trailing whitespace, but WinIE 7 doesn't.
+// Mozilla 1.8 and WinIE 7 both accept the empty string, but neither accept a whitespace-only string.
+// We want to accept all the values that either of these browsers accept, but not other values.
+static const char* supported_javascript_types[] = {
+ "text/javascript",
+ "text/ecmascript",
+ "application/javascript",
+ "application/ecmascript",
+ "application/x-javascript",
+ "text/javascript1.1",
+ "text/javascript1.2",
+ "text/javascript1.3",
+ "text/jscript",
+ "text/livescript"
+};
+
+static const char* view_source_types[] = {
+ "text/xml",
+ "text/xsl",
+ "application/xml",
+ "application/rss+xml",
+ "application/atom+xml",
+ "image/svg+xml"
+};
+
+// For faster lookup
+static stdext::hash_set<string>* image_map = NULL;
+static stdext::hash_set<string>* non_image_map = NULL;
+static stdext::hash_set<string>* javascript_map = NULL;
+static stdext::hash_set<string>* view_source_map = NULL;
+
+static void InitializeMimeTypeMaps() {
+ image_map = new stdext::hash_set<string>;
+ non_image_map = new stdext::hash_set<string>;
+ javascript_map = new stdext::hash_set<string>;
+ view_source_map = new stdext::hash_set<string>;
+
+ for (int i = 0; i < arraysize(supported_image_types); ++i)
+ image_map->insert(supported_image_types[i]);
+
+ // Initialize the supported non-image types
+ for (int i = 0; i < arraysize(supported_non_image_types); ++i)
+ non_image_map->insert(supported_non_image_types[i]);
+ for (int i = 0; i < arraysize(supported_javascript_types); ++i)
+ non_image_map->insert(supported_javascript_types[i]);
+
+ for (int i = 0; i < arraysize(supported_javascript_types); ++i)
+ javascript_map->insert(supported_javascript_types[i]);
+
+ for (int i = 0; i < arraysize(view_source_types); ++i)
+ view_source_map->insert(view_source_types[i]);
+}
+
+bool IsSupportedImageMimeType(const char* mime_type) {
+ if (!image_map)
+ InitializeMimeTypeMaps();
+ return image_map->find(mime_type) != image_map->end();
+}
+
+bool IsSupportedNonImageMimeType(const char* mime_type) {
+ if (!non_image_map)
+ InitializeMimeTypeMaps();
+ return non_image_map->find(mime_type) != non_image_map->end();
+}
+
+bool IsSupportedJavascriptMimeType(const char* mime_type) {
+ if (!javascript_map)
+ InitializeMimeTypeMaps();
+ return javascript_map->find(mime_type) != javascript_map->end();
+}
+
+bool IsViewSourceMimeType(const char* mime_type) {
+ if (!view_source_map)
+ InitializeMimeTypeMaps();
+ return view_source_map->find(mime_type) != view_source_map->end();
+}
+
+// Mirrors WebViewImpl::CanShowMIMEType()
+bool IsSupportedMimeType(const std::string& mime_type) {
+ if (mime_type.compare(0, 5, "text/") == 0 ||
+ (mime_type.compare(0, 6, "image/") == 0 &&
+ mime_util::IsSupportedImageMimeType(mime_type.c_str())) ||
+ mime_util::IsSupportedNonImageMimeType(mime_type.c_str()))
+ return true;
+ return false;
+}
+
+bool MatchesMimeType(const std::string &mime_type_pattern,
+ const std::string &mime_type) {
+ // verify caller is passing lowercase
+ DCHECK(mime_type_pattern == StringToLowerASCII(mime_type_pattern));
+ DCHECK(mime_type == StringToLowerASCII(mime_type));
+
+ // This comparison handles absolute maching and also basic
+ // wildcards. The plugin mime types could be:
+ // application/x-foo
+ // application/*
+ // application/*+xml
+ // *
+ if (mime_type_pattern.empty())
+ return false;
+
+ const std::string::size_type star = mime_type_pattern.find('*');
+
+ if (star == std::string::npos)
+ return mime_type_pattern == mime_type;
+
+ // Test length to prevent overlap between |left| and |right|.
+ if (mime_type.length() < mime_type_pattern.length() - 1)
+ return false;
+
+ const std::string left(mime_type_pattern.substr(0, star));
+ const std::string right(mime_type_pattern.substr(star + 1));
+
+ if (mime_type.find(left) != 0)
+ return false;
+
+ if (!right.empty() &&
+ mime_type.rfind(right) != mime_type.length() - right.length())
+ return false;
+
+ return true;
+}
+
+} // namespace mime_util