Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_protocols.h" | 5 #include "chrome/browser/extensions/extension_protocols.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "net/http/http_response_info.h" | 31 #include "net/http/http_response_info.h" |
| 32 #include "net/http/http_response_headers.h" | 32 #include "net/http/http_response_headers.h" |
| 33 #include "net/url_request/url_request_error_job.h" | 33 #include "net/url_request/url_request_error_job.h" |
| 34 #include "net/url_request/url_request_file_job.h" | 34 #include "net/url_request/url_request_file_job.h" |
| 35 #include "net/url_request/url_request_simple_job.h" | 35 #include "net/url_request/url_request_simple_job.h" |
| 36 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
| 37 | 37 |
| 38 namespace { | 38 namespace { |
| 39 | 39 |
| 40 net::HttpResponseHeaders* BuildHttpHeaders( | 40 net::HttpResponseHeaders* BuildHttpHeaders( |
| 41 const std::string& content_security_policy) { | 41 const std::string& content_security_policy, bool send_cors_header) { |
| 42 std::string raw_headers; | 42 std::string raw_headers; |
| 43 raw_headers.append("HTTP/1.1 200 OK"); | 43 raw_headers.append("HTTP/1.1 200 OK"); |
| 44 if (!content_security_policy.empty()) { | 44 if (!content_security_policy.empty()) { |
| 45 raw_headers.append(1, '\0'); | 45 raw_headers.append(1, '\0'); |
| 46 raw_headers.append("X-WebKit-CSP: "); | 46 raw_headers.append("X-WebKit-CSP: "); |
| 47 raw_headers.append(content_security_policy); | 47 raw_headers.append(content_security_policy); |
| 48 } | 48 } |
| 49 | |
| 50 if (send_cors_header) { | |
| 51 raw_headers.append(1, '\0'); | |
| 52 raw_headers.append("Access-Control-Allow-Origin: *"); | |
| 53 } | |
| 49 raw_headers.append(2, '\0'); | 54 raw_headers.append(2, '\0'); |
| 50 return new net::HttpResponseHeaders(raw_headers); | 55 return new net::HttpResponseHeaders(raw_headers); |
| 51 } | 56 } |
| 52 | 57 |
| 53 class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { | 58 class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { |
| 54 public: | 59 public: |
| 55 URLRequestResourceBundleJob( | 60 URLRequestResourceBundleJob( |
| 56 net::URLRequest* request, const FilePath& filename, int resource_id, | 61 net::URLRequest* request, const FilePath& filename, int resource_id, |
| 57 const std::string& content_security_policy) | 62 const std::string& content_security_policy, bool send_cors_header) |
| 58 : net::URLRequestSimpleJob(request), | 63 : net::URLRequestSimpleJob(request), |
| 59 filename_(filename), | 64 filename_(filename), |
| 60 resource_id_(resource_id) { | 65 resource_id_(resource_id) { |
| 61 response_info_.headers = BuildHttpHeaders(content_security_policy); | 66 response_info_.headers = BuildHttpHeaders(content_security_policy, |
| 67 send_cors_header); | |
| 62 } | 68 } |
| 63 | 69 |
| 64 // Overridden from URLRequestSimpleJob: | 70 // Overridden from URLRequestSimpleJob: |
| 65 virtual bool GetData(std::string* mime_type, | 71 virtual bool GetData(std::string* mime_type, |
| 66 std::string* charset, | 72 std::string* charset, |
| 67 std::string* data) const OVERRIDE { | 73 std::string* data) const OVERRIDE { |
| 68 const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 74 const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 69 *data = rb.GetRawDataResource(resource_id_).as_string(); | 75 *data = rb.GetRawDataResource(resource_id_).as_string(); |
| 70 | 76 |
| 71 // Requests should not block on the disk! On Windows this goes to the | 77 // Requests should not block on the disk! On Windows this goes to the |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 102 net::HttpResponseInfo response_info_; | 108 net::HttpResponseInfo response_info_; |
| 103 }; | 109 }; |
| 104 | 110 |
| 105 class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob { | 111 class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob { |
| 106 public: | 112 public: |
| 107 GeneratedBackgroundPageJob(net::URLRequest* request, | 113 GeneratedBackgroundPageJob(net::URLRequest* request, |
| 108 const scoped_refptr<const Extension> extension, | 114 const scoped_refptr<const Extension> extension, |
| 109 const std::string& content_security_policy) | 115 const std::string& content_security_policy) |
| 110 : net::URLRequestSimpleJob(request), | 116 : net::URLRequestSimpleJob(request), |
| 111 extension_(extension) { | 117 extension_(extension) { |
| 112 response_info_.headers = BuildHttpHeaders(content_security_policy); | 118 response_info_.headers = BuildHttpHeaders(content_security_policy, false); |
|
Aaron Boodman
2012/01/27 22:36:46
Nit: use a named constant here for readability.
Cris Neckar
2012/01/27 22:58:23
Done.
| |
| 113 } | 119 } |
| 114 | 120 |
| 115 // Overridden from URLRequestSimpleJob: | 121 // Overridden from URLRequestSimpleJob: |
| 116 virtual bool GetData(std::string* mime_type, | 122 virtual bool GetData(std::string* mime_type, |
| 117 std::string* charset, | 123 std::string* charset, |
| 118 std::string* data) const OVERRIDE { | 124 std::string* data) const OVERRIDE { |
| 119 *mime_type = "text/html"; | 125 *mime_type = "text/html"; |
| 120 *charset = "utf-8"; | 126 *charset = "utf-8"; |
| 121 | 127 |
| 122 *data = "<!DOCTYPE html>\n<body>\n"; | 128 *data = "<!DOCTYPE html>\n<body>\n"; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 135 | 141 |
| 136 private: | 142 private: |
| 137 scoped_refptr<const Extension> extension_; | 143 scoped_refptr<const Extension> extension_; |
| 138 net::HttpResponseInfo response_info_; | 144 net::HttpResponseInfo response_info_; |
| 139 }; | 145 }; |
| 140 | 146 |
| 141 class URLRequestExtensionJob : public net::URLRequestFileJob { | 147 class URLRequestExtensionJob : public net::URLRequestFileJob { |
| 142 public: | 148 public: |
| 143 URLRequestExtensionJob(net::URLRequest* request, | 149 URLRequestExtensionJob(net::URLRequest* request, |
| 144 const FilePath& filename, | 150 const FilePath& filename, |
| 145 const std::string& content_security_policy) | 151 const std::string& content_security_policy, |
| 152 bool send_cors_header) | |
| 146 : net::URLRequestFileJob(request, filename) { | 153 : net::URLRequestFileJob(request, filename) { |
| 147 response_info_.headers = BuildHttpHeaders(content_security_policy); | 154 response_info_.headers = BuildHttpHeaders(content_security_policy, |
| 155 send_cors_header); | |
| 148 } | 156 } |
| 149 | 157 |
| 150 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { | 158 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { |
| 151 *info = response_info_; | 159 *info = response_info_; |
| 152 } | 160 } |
| 153 | 161 |
| 154 net::HttpResponseInfo response_info_; | 162 net::HttpResponseInfo response_info_; |
| 155 }; | 163 }; |
| 156 | 164 |
| 157 bool ExtensionCanLoadInIncognito(const std::string& extension_id, | 165 bool ExtensionCanLoadInIncognito(const std::string& extension_id, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 extension_info_map_->disabled_extensions().GetByID(extension_id); | 256 extension_info_map_->disabled_extensions().GetByID(extension_id); |
| 249 if (URLIsForExtensionIcon(request->url(), disabled_extension)) | 257 if (URLIsForExtensionIcon(request->url(), disabled_extension)) |
| 250 directory_path = disabled_extension->path(); | 258 directory_path = disabled_extension->path(); |
| 251 if (directory_path.value().empty()) { | 259 if (directory_path.value().empty()) { |
| 252 LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id; | 260 LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id; |
| 253 return NULL; | 261 return NULL; |
| 254 } | 262 } |
| 255 } | 263 } |
| 256 | 264 |
| 257 std::string content_security_policy; | 265 std::string content_security_policy; |
| 258 if (extension) | 266 bool send_cors_header = false; |
| 267 if (extension) { | |
| 259 content_security_policy = extension->content_security_policy(); | 268 content_security_policy = extension->content_security_policy(); |
| 269 if ((extension->manifest_version() >= 2 || | |
| 270 extension->HasWebAccessibleResources()) && | |
| 271 extension->IsResourceWebAccessible(request->url().path())) | |
| 272 send_cors_header = true; | |
| 273 } | |
| 260 | 274 |
| 261 std::string path = request->url().path(); | 275 std::string path = request->url().path(); |
| 262 if (path.size() > 1 && | 276 if (path.size() > 1 && |
| 263 path.substr(1) == extension_filenames::kGeneratedBackgroundPageFilename) { | 277 path.substr(1) == extension_filenames::kGeneratedBackgroundPageFilename) { |
| 264 return new GeneratedBackgroundPageJob( | 278 return new GeneratedBackgroundPageJob( |
| 265 request, extension, content_security_policy); | 279 request, extension, content_security_policy); |
| 266 } | 280 } |
| 267 | 281 |
| 268 FilePath resources_path; | 282 FilePath resources_path; |
| 269 if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) && | 283 if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) && |
| 270 directory_path.DirName() == resources_path) { | 284 directory_path.DirName() == resources_path) { |
| 271 FilePath relative_path = directory_path.BaseName().Append( | 285 FilePath relative_path = directory_path.BaseName().Append( |
| 272 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); | 286 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); |
| 273 #if defined(OS_WIN) | 287 #if defined(OS_WIN) |
| 274 relative_path = relative_path.NormalizeWindowsPathSeparators(); | 288 relative_path = relative_path.NormalizeWindowsPathSeparators(); |
| 275 #endif | 289 #endif |
| 276 | 290 |
| 277 // TODO(tc): Make a map of FilePath -> resource ids so we don't have to | 291 // TODO(tc): Make a map of FilePath -> resource ids so we don't have to |
| 278 // covert to FilePaths all the time. This will be more useful as we add | 292 // covert to FilePaths all the time. This will be more useful as we add |
| 279 // more resources. | 293 // more resources. |
| 280 for (size_t i = 0; i < kComponentExtensionResourcesSize; ++i) { | 294 for (size_t i = 0; i < kComponentExtensionResourcesSize; ++i) { |
| 281 FilePath bm_resource_path = | 295 FilePath bm_resource_path = |
| 282 FilePath().AppendASCII(kComponentExtensionResources[i].name); | 296 FilePath().AppendASCII(kComponentExtensionResources[i].name); |
| 283 #if defined(OS_WIN) | 297 #if defined(OS_WIN) |
| 284 bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators(); | 298 bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators(); |
| 285 #endif | 299 #endif |
| 286 if (relative_path == bm_resource_path) { | 300 if (relative_path == bm_resource_path) { |
| 287 return new URLRequestResourceBundleJob(request, relative_path, | 301 return new URLRequestResourceBundleJob(request, relative_path, |
| 288 kComponentExtensionResources[i].value, content_security_policy); | 302 kComponentExtensionResources[i].value, content_security_policy, |
| 303 send_cors_header); | |
| 289 } | 304 } |
| 290 } | 305 } |
| 291 } | 306 } |
| 292 // TODO(tc): Move all of these files into resources.pak so we don't break | 307 // TODO(tc): Move all of these files into resources.pak so we don't break |
| 293 // when updating on Linux. | 308 // when updating on Linux. |
| 294 ExtensionResource resource(extension_id, directory_path, | 309 ExtensionResource resource(extension_id, directory_path, |
| 295 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); | 310 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); |
| 296 | 311 |
| 297 FilePath resource_file_path; | 312 FilePath resource_file_path; |
| 298 { | 313 { |
| 299 // Getting the file path will touch the file system. Fixing | 314 // Getting the file path will touch the file system. Fixing |
| 300 // crbug.com/59849 would also fix this. Suppress the error for now. | 315 // crbug.com/59849 would also fix this. Suppress the error for now. |
| 301 base::ThreadRestrictions::ScopedAllowIO allow_io; | 316 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 302 resource_file_path = resource.GetFilePath(); | 317 resource_file_path = resource.GetFilePath(); |
| 303 } | 318 } |
| 304 | 319 |
| 305 return new URLRequestExtensionJob(request, resource_file_path, | 320 return new URLRequestExtensionJob(request, resource_file_path, |
| 306 content_security_policy); | 321 content_security_policy, send_cors_header); |
| 307 } | 322 } |
| 308 | 323 |
| 309 } // namespace | 324 } // namespace |
| 310 | 325 |
| 311 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( | 326 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( |
| 312 bool is_incognito, | 327 bool is_incognito, |
| 313 ExtensionInfoMap* extension_info_map) { | 328 ExtensionInfoMap* extension_info_map) { |
| 314 return new ExtensionProtocolHandler(is_incognito, extension_info_map); | 329 return new ExtensionProtocolHandler(is_incognito, extension_info_map); |
| 315 } | 330 } |
| OLD | NEW |