Index: chrome/browser/extensions/extension_protocol.cc |
diff --git a/chrome/browser/extensions/extension_protocol.cc b/chrome/browser/extensions/extension_protocol.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..34b9a0e10d0f19efc3b9c845662f85d873c75689 |
--- /dev/null |
+++ b/chrome/browser/extensions/extension_protocol.cc |
@@ -0,0 +1,75 @@ |
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/extensions/extension_protocol.h" |
+ |
+#include "base/string_util.h" |
+#include "chrome/browser/net/chrome_url_request_context.h" |
+#include "googleurl/src/url_util.h" |
+#include "net/base/net_util.h" |
+#include "net/url_request/url_request_file_job.h" |
+ |
+static const char kExtensionURLScheme[] = "chrome-extension"; |
+ |
+FilePath GetPathForExtensionResource(const FilePath& extension_path, |
+ const std::string& url_path) { |
+ DCHECK(extension_path.IsAbsolute()); |
+ DCHECK(url_path.length() > 0 && url_path[0] == '/'); |
+ |
+ // Build up a file:// URL and convert that back to a FilePath. This avoids |
+ // URL encoding and path separator issues. |
+ |
+ // Convert the extension's root to a file:// URL. |
+ GURL extension_url = net::FilePathToFileURL(extension_path); |
+ if (!extension_url.is_valid()) |
+ return FilePath(); |
+ |
+ // Append the requested path. |
+ GURL::Replacements replacements; |
+ std::string new_path(extension_url.path()); |
+ new_path += url_path; |
+ replacements.SetPathStr(new_path); |
+ GURL file_url = extension_url.ReplaceComponents(replacements); |
+ if (!file_url.is_valid()) |
+ return FilePath(); |
+ |
+ // Convert the result back to a FilePath. |
+ FilePath ret_val; |
+ if (!net::FileURLToFilePath(file_url, &ret_val)) |
+ return FilePath(); |
+ |
+ // Double-check that the path we ended up with is actually inside the |
+ // extension root. |
+ if (!extension_path.Contains(ret_val)) |
+ return FilePath(); |
+ |
+ return ret_val; |
+} |
+ |
+// Creates a URLRequestJob instance for an extension URL. This is the factory |
+// function that is registered with URLRequest. |
+static URLRequestJob* CreateURLRequestJob(URLRequest* request, |
+ const std::string& scheme) { |
+ ChromeURLRequestContext* context = |
+ static_cast<ChromeURLRequestContext*>(request->context()); |
+ |
+ FilePath extension_path = context->GetPathForExtension(request->url().host()); |
+ if (extension_path.value().empty()) |
+ return NULL; |
+ |
+ FilePath path = GetPathForExtensionResource(extension_path, |
+ request->url().path()); |
+ if (path.value().empty()) |
+ return NULL; |
+ |
+ return new URLRequestFileJob(request, path); |
+} |
+ |
+void RegisterExtensionProtocol() { |
+ // Being a standard scheme allows us to resolve relative paths |
+ url_util::AddStandardScheme(kExtensionURLScheme); |
+ |
+ URLRequest::RegisterProtocolFactory(kExtensionURLScheme, |
+ &CreateURLRequestJob); |
+} |