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 |