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 const bool send_cors_headers = false; |
| 119 response_info_.headers = BuildHttpHeaders(content_security_policy, |
| 120 send_cors_headers); |
113 } | 121 } |
114 | 122 |
115 // Overridden from URLRequestSimpleJob: | 123 // Overridden from URLRequestSimpleJob: |
116 virtual bool GetData(std::string* mime_type, | 124 virtual bool GetData(std::string* mime_type, |
117 std::string* charset, | 125 std::string* charset, |
118 std::string* data) const OVERRIDE { | 126 std::string* data) const OVERRIDE { |
119 *mime_type = "text/html"; | 127 *mime_type = "text/html"; |
120 *charset = "utf-8"; | 128 *charset = "utf-8"; |
121 | 129 |
122 *data = "<!DOCTYPE html>\n<body>\n"; | 130 *data = "<!DOCTYPE html>\n<body>\n"; |
(...skipping 12 matching lines...) Expand all Loading... |
135 | 143 |
136 private: | 144 private: |
137 scoped_refptr<const Extension> extension_; | 145 scoped_refptr<const Extension> extension_; |
138 net::HttpResponseInfo response_info_; | 146 net::HttpResponseInfo response_info_; |
139 }; | 147 }; |
140 | 148 |
141 class URLRequestExtensionJob : public net::URLRequestFileJob { | 149 class URLRequestExtensionJob : public net::URLRequestFileJob { |
142 public: | 150 public: |
143 URLRequestExtensionJob(net::URLRequest* request, | 151 URLRequestExtensionJob(net::URLRequest* request, |
144 const FilePath& filename, | 152 const FilePath& filename, |
145 const std::string& content_security_policy) | 153 const std::string& content_security_policy, |
| 154 bool send_cors_header) |
146 : net::URLRequestFileJob(request, filename) { | 155 : net::URLRequestFileJob(request, filename) { |
147 response_info_.headers = BuildHttpHeaders(content_security_policy); | 156 response_info_.headers = BuildHttpHeaders(content_security_policy, |
| 157 send_cors_header); |
148 } | 158 } |
149 | 159 |
150 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { | 160 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { |
151 *info = response_info_; | 161 *info = response_info_; |
152 } | 162 } |
153 | 163 |
154 net::HttpResponseInfo response_info_; | 164 net::HttpResponseInfo response_info_; |
155 }; | 165 }; |
156 | 166 |
157 bool ExtensionCanLoadInIncognito(const std::string& extension_id, | 167 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); | 258 extension_info_map_->disabled_extensions().GetByID(extension_id); |
249 if (URLIsForExtensionIcon(request->url(), disabled_extension)) | 259 if (URLIsForExtensionIcon(request->url(), disabled_extension)) |
250 directory_path = disabled_extension->path(); | 260 directory_path = disabled_extension->path(); |
251 if (directory_path.value().empty()) { | 261 if (directory_path.value().empty()) { |
252 LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id; | 262 LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id; |
253 return NULL; | 263 return NULL; |
254 } | 264 } |
255 } | 265 } |
256 | 266 |
257 std::string content_security_policy; | 267 std::string content_security_policy; |
258 if (extension) | 268 bool send_cors_header = false; |
| 269 if (extension) { |
259 content_security_policy = extension->content_security_policy(); | 270 content_security_policy = extension->content_security_policy(); |
| 271 if ((extension->manifest_version() >= 2 || |
| 272 extension->HasWebAccessibleResources()) && |
| 273 extension->IsResourceWebAccessible(request->url().path())) |
| 274 send_cors_header = true; |
| 275 } |
260 | 276 |
261 std::string path = request->url().path(); | 277 std::string path = request->url().path(); |
262 if (path.size() > 1 && | 278 if (path.size() > 1 && |
263 path.substr(1) == extension_filenames::kGeneratedBackgroundPageFilename) { | 279 path.substr(1) == extension_filenames::kGeneratedBackgroundPageFilename) { |
264 return new GeneratedBackgroundPageJob( | 280 return new GeneratedBackgroundPageJob( |
265 request, extension, content_security_policy); | 281 request, extension, content_security_policy); |
266 } | 282 } |
267 | 283 |
268 FilePath resources_path; | 284 FilePath resources_path; |
269 if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) && | 285 if (PathService::Get(chrome::DIR_RESOURCES, &resources_path) && |
270 directory_path.DirName() == resources_path) { | 286 directory_path.DirName() == resources_path) { |
271 FilePath relative_path = directory_path.BaseName().Append( | 287 FilePath relative_path = directory_path.BaseName().Append( |
272 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); | 288 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); |
273 #if defined(OS_WIN) | 289 #if defined(OS_WIN) |
274 relative_path = relative_path.NormalizeWindowsPathSeparators(); | 290 relative_path = relative_path.NormalizeWindowsPathSeparators(); |
275 #endif | 291 #endif |
276 | 292 |
277 // TODO(tc): Make a map of FilePath -> resource ids so we don't have to | 293 // 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 | 294 // covert to FilePaths all the time. This will be more useful as we add |
279 // more resources. | 295 // more resources. |
280 for (size_t i = 0; i < kComponentExtensionResourcesSize; ++i) { | 296 for (size_t i = 0; i < kComponentExtensionResourcesSize; ++i) { |
281 FilePath bm_resource_path = | 297 FilePath bm_resource_path = |
282 FilePath().AppendASCII(kComponentExtensionResources[i].name); | 298 FilePath().AppendASCII(kComponentExtensionResources[i].name); |
283 #if defined(OS_WIN) | 299 #if defined(OS_WIN) |
284 bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators(); | 300 bm_resource_path = bm_resource_path.NormalizeWindowsPathSeparators(); |
285 #endif | 301 #endif |
286 if (relative_path == bm_resource_path) { | 302 if (relative_path == bm_resource_path) { |
287 return new URLRequestResourceBundleJob(request, relative_path, | 303 return new URLRequestResourceBundleJob(request, relative_path, |
288 kComponentExtensionResources[i].value, content_security_policy); | 304 kComponentExtensionResources[i].value, content_security_policy, |
| 305 send_cors_header); |
289 } | 306 } |
290 } | 307 } |
291 } | 308 } |
292 // TODO(tc): Move all of these files into resources.pak so we don't break | 309 // TODO(tc): Move all of these files into resources.pak so we don't break |
293 // when updating on Linux. | 310 // when updating on Linux. |
294 ExtensionResource resource(extension_id, directory_path, | 311 ExtensionResource resource(extension_id, directory_path, |
295 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); | 312 extension_file_util::ExtensionURLToRelativeFilePath(request->url())); |
296 | 313 |
297 FilePath resource_file_path; | 314 FilePath resource_file_path; |
298 { | 315 { |
299 // Getting the file path will touch the file system. Fixing | 316 // Getting the file path will touch the file system. Fixing |
300 // crbug.com/59849 would also fix this. Suppress the error for now. | 317 // crbug.com/59849 would also fix this. Suppress the error for now. |
301 base::ThreadRestrictions::ScopedAllowIO allow_io; | 318 base::ThreadRestrictions::ScopedAllowIO allow_io; |
302 resource_file_path = resource.GetFilePath(); | 319 resource_file_path = resource.GetFilePath(); |
303 } | 320 } |
304 | 321 |
305 return new URLRequestExtensionJob(request, resource_file_path, | 322 return new URLRequestExtensionJob(request, resource_file_path, |
306 content_security_policy); | 323 content_security_policy, send_cors_header); |
307 } | 324 } |
308 | 325 |
309 } // namespace | 326 } // namespace |
310 | 327 |
311 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( | 328 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( |
312 bool is_incognito, | 329 bool is_incognito, |
313 ExtensionInfoMap* extension_info_map) { | 330 ExtensionInfoMap* extension_info_map) { |
314 return new ExtensionProtocolHandler(is_incognito, extension_info_map); | 331 return new ExtensionProtocolHandler(is_incognito, extension_info_map); |
315 } | 332 } |
OLD | NEW |