Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: chrome/browser/extensions/extension_protocols.cc

Issue 10696135: Offload disk accesses to WorkerPool in ExtensionProtocolHandler (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/histogram_internals_request_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop.h" 13 #include "base/message_loop.h"
13 #include "base/path_service.h" 14 #include "base/path_service.h"
14 #include "base/string_util.h" 15 #include "base/string_util.h"
15 #include "base/stringprintf.h" 16 #include "base/stringprintf.h"
16 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 #include "base/threading/worker_pool.h"
17 #include "build/build_config.h" 19 #include "build/build_config.h"
18 #include "chrome/browser/extensions/extension_info_map.h" 20 #include "chrome/browser/extensions/extension_info_map.h"
19 #include "chrome/browser/net/chrome_url_request_context.h" 21 #include "chrome/browser/net/chrome_url_request_context.h"
20 #include "chrome/common/chrome_paths.h" 22 #include "chrome/common/chrome_paths.h"
21 #include "chrome/common/extensions/extension.h" 23 #include "chrome/common/extensions/extension.h"
22 #include "chrome/common/extensions/extension_file_util.h" 24 #include "chrome/common/extensions/extension_file_util.h"
23 #include "chrome/common/extensions/extension_resource.h" 25 #include "chrome/common/extensions/extension_resource.h"
24 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
25 #include "content/public/browser/resource_request_info.h" 27 #include "content/public/browser/resource_request_info.h"
26 #include "googleurl/src/url_util.h" 28 #include "googleurl/src/url_util.h"
(...skipping 24 matching lines...) Expand all
51 } 53 }
52 54
53 if (send_cors_header) { 55 if (send_cors_header) {
54 raw_headers.append(1, '\0'); 56 raw_headers.append(1, '\0');
55 raw_headers.append("Access-Control-Allow-Origin: *"); 57 raw_headers.append("Access-Control-Allow-Origin: *");
56 } 58 }
57 raw_headers.append(2, '\0'); 59 raw_headers.append(2, '\0');
58 return new net::HttpResponseHeaders(raw_headers); 60 return new net::HttpResponseHeaders(raw_headers);
59 } 61 }
60 62
63 void ReadMimeTypeFromFile(const FilePath& filename,
64 std::string* mime_type,
65 bool* result) {
66 *result = net::GetMimeTypeFromFile(filename, mime_type);
67 }
68
61 class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { 69 class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
62 public: 70 public:
63 URLRequestResourceBundleJob( 71 URLRequestResourceBundleJob(
64 net::URLRequest* request, const FilePath& filename, int resource_id, 72 net::URLRequest* request, const FilePath& filename, int resource_id,
65 const std::string& content_security_policy, bool send_cors_header) 73 const std::string& content_security_policy, bool send_cors_header)
66 : net::URLRequestSimpleJob(request), 74 : net::URLRequestSimpleJob(request),
67 filename_(filename), 75 filename_(filename),
68 resource_id_(resource_id) { 76 resource_id_(resource_id),
77 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
69 response_info_.headers = BuildHttpHeaders(content_security_policy, 78 response_info_.headers = BuildHttpHeaders(content_security_policy,
70 send_cors_header); 79 send_cors_header);
71 } 80 }
72 81
73 // Overridden from URLRequestSimpleJob: 82 // Overridden from URLRequestSimpleJob:
74 virtual bool GetData(std::string* mime_type, 83 virtual int GetData(std::string* mime_type,
75 std::string* charset, 84 std::string* charset,
76 std::string* data) const OVERRIDE { 85 std::string* data,
86 const net::CompletionCallback& callback) const OVERRIDE {
77 const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 87 const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
78 *data = rb.GetRawDataResource( 88 *data = rb.GetRawDataResource(
79 resource_id_, ui::SCALE_FACTOR_NONE).as_string(); 89 resource_id_, ui::SCALE_FACTOR_NONE).as_string();
80 90
81 // Requests should not block on the disk! On Windows this goes to the 91 std::string* read_mime_type = new std::string;
82 // registry. 92 bool* read_result = new bool;
83 // http://code.google.com/p/chromium/issues/detail?id=59849 93 bool posted = base::WorkerPool::PostTaskAndReply(
84 bool result; 94 FROM_HERE,
85 { 95 base::Bind(&ReadMimeTypeFromFile, filename_,
86 base::ThreadRestrictions::ScopedAllowIO allow_io; 96 base::Unretained(read_mime_type),
87 result = net::GetMimeTypeFromFile(filename_, mime_type); 97 base::Unretained(read_result)),
88 } 98 base::Bind(&URLRequestResourceBundleJob::OnMimeTypeRead,
99 weak_factory_.GetWeakPtr(),
100 mime_type, charset, data,
101 base::Owned(read_mime_type),
102 base::Owned(read_result),
103 callback),
104 true /* task is slow */);
105 DCHECK(posted);
89 106
90 if (StartsWithASCII(*mime_type, "text/", false)) { 107 return net::ERR_IO_PENDING;
91 // All of our HTML files should be UTF-8 and for other resource types
92 // (like images), charset doesn't matter.
93 DCHECK(IsStringUTF8(*data));
94 *charset = "utf-8";
95 }
96 return result;
97 } 108 }
98 109
99 virtual void GetResponseInfo(net::HttpResponseInfo* info) { 110 virtual void GetResponseInfo(net::HttpResponseInfo* info) {
100 *info = response_info_; 111 *info = response_info_;
101 } 112 }
102 113
103 private: 114 private:
104 virtual ~URLRequestResourceBundleJob() { } 115 virtual ~URLRequestResourceBundleJob() { }
105 116
117 void OnMimeTypeRead(std::string* out_mime_type,
118 std::string* charset,
119 std::string* data,
120 std::string* read_mime_type,
121 bool* read_result,
122 const net::CompletionCallback& callback) {
123 *out_mime_type = *read_mime_type;
124 if (StartsWithASCII(*read_mime_type, "text/", false)) {
125 // All of our HTML files should be UTF-8 and for other resource types
126 // (like images), charset doesn't matter.
127 DCHECK(IsStringUTF8(*data));
128 *charset = "utf-8";
129 }
130 int result = *read_result? net::OK: net::ERR_INVALID_URL;
131 callback.Run(result);
132 }
133
106 // We need the filename of the resource to determine the mime type. 134 // We need the filename of the resource to determine the mime type.
107 FilePath filename_; 135 FilePath filename_;
108 136
109 // The resource bundle id to load. 137 // The resource bundle id to load.
110 int resource_id_; 138 int resource_id_;
111 139
112 net::HttpResponseInfo response_info_; 140 net::HttpResponseInfo response_info_;
141
142 mutable base::WeakPtrFactory<URLRequestResourceBundleJob> weak_factory_;
113 }; 143 };
114 144
115 class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob { 145 class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob {
116 public: 146 public:
117 GeneratedBackgroundPageJob(net::URLRequest* request, 147 GeneratedBackgroundPageJob(net::URLRequest* request,
118 const scoped_refptr<const Extension> extension, 148 const scoped_refptr<const Extension> extension,
119 const std::string& content_security_policy) 149 const std::string& content_security_policy)
120 : net::URLRequestSimpleJob(request), 150 : net::URLRequestSimpleJob(request),
121 extension_(extension) { 151 extension_(extension) {
122 const bool send_cors_headers = false; 152 const bool send_cors_headers = false;
123 response_info_.headers = BuildHttpHeaders(content_security_policy, 153 response_info_.headers = BuildHttpHeaders(content_security_policy,
124 send_cors_headers); 154 send_cors_headers);
125 } 155 }
126 156
127 // Overridden from URLRequestSimpleJob: 157 // Overridden from URLRequestSimpleJob:
128 virtual bool GetData(std::string* mime_type, 158 virtual int GetData(std::string* mime_type,
129 std::string* charset, 159 std::string* charset,
130 std::string* data) const OVERRIDE { 160 std::string* data,
161 const net::CompletionCallback& callback) const OVERRIDE {
131 *mime_type = "text/html"; 162 *mime_type = "text/html";
132 *charset = "utf-8"; 163 *charset = "utf-8";
133 164
134 *data = "<!DOCTYPE html>\n<body>\n"; 165 *data = "<!DOCTYPE html>\n<body>\n";
135 for (size_t i = 0; i < extension_->background_scripts().size(); ++i) { 166 for (size_t i = 0; i < extension_->background_scripts().size(); ++i) {
136 *data += "<script src=\""; 167 *data += "<script src=\"";
137 *data += extension_->background_scripts()[i]; 168 *data += extension_->background_scripts()[i];
138 *data += "\"></script>\n"; 169 *data += "\"></script>\n";
139 } 170 }
140 171
141 return true; 172 return net::OK;
142 } 173 }
143 174
144 virtual void GetResponseInfo(net::HttpResponseInfo* info) { 175 virtual void GetResponseInfo(net::HttpResponseInfo* info) {
145 *info = response_info_; 176 *info = response_info_;
146 } 177 }
147 178
148 private: 179 private:
149 virtual ~GeneratedBackgroundPageJob() {} 180 virtual ~GeneratedBackgroundPageJob() {}
150 181
151 scoped_refptr<const Extension> extension_; 182 scoped_refptr<const Extension> extension_;
152 net::HttpResponseInfo response_info_; 183 net::HttpResponseInfo response_info_;
153 }; 184 };
154 185
186 void ReadResourceFilePath(const ExtensionResource& resource,
187 FilePath* file_path) {
188 *file_path = resource.GetFilePath();
189 }
190
155 class URLRequestExtensionJob : public net::URLRequestFileJob { 191 class URLRequestExtensionJob : public net::URLRequestFileJob {
156 public: 192 public:
157 URLRequestExtensionJob(net::URLRequest* request, 193 URLRequestExtensionJob(net::URLRequest* request,
158 const FilePath& filename, 194 const std::string& extension_id,
195 const FilePath& directory_path,
159 const std::string& content_security_policy, 196 const std::string& content_security_policy,
160 bool send_cors_header) 197 bool send_cors_header)
161 : net::URLRequestFileJob(request, filename) { 198 : net::URLRequestFileJob(request, FilePath()),
199 // TODO(tc): Move all of these files into resources.pak so we don't break
200 // when updating on Linux.
201 resource_(extension_id, directory_path,
202 extension_file_util::ExtensionURLToRelativeFilePath(
203 request->url())),
204 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
162 response_info_.headers = BuildHttpHeaders(content_security_policy, 205 response_info_.headers = BuildHttpHeaders(content_security_policy,
163 send_cors_header); 206 send_cors_header);
164 } 207 }
165 208
166 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { 209 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE {
167 *info = response_info_; 210 *info = response_info_;
168 } 211 }
169 212
213 virtual void Start() OVERRIDE {
214 FilePath* read_file_path = new FilePath;
215 bool posted = base::WorkerPool::PostTaskAndReply(
216 FROM_HERE,
217 base::Bind(&ReadResourceFilePath, resource_,
218 base::Unretained(read_file_path)),
219 base::Bind(&URLRequestExtensionJob::OnFilePathRead,
220 weak_factory_.GetWeakPtr(),
221 base::Owned(read_file_path)),
222 true /* task is slow */);
223 DCHECK(posted);
224 }
225
170 private: 226 private:
171 virtual ~URLRequestExtensionJob() {} 227 virtual ~URLRequestExtensionJob() {}
172 228
229 void OnFilePathRead(FilePath* read_file_path) {
230 file_path_ = *read_file_path;
231 URLRequestFileJob::Start();
232 }
233
173 net::HttpResponseInfo response_info_; 234 net::HttpResponseInfo response_info_;
235 ExtensionResource resource_;
236 base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_;
174 }; 237 };
175 238
176 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info, 239 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info,
177 const std::string& extension_id, 240 const std::string& extension_id,
178 ExtensionInfoMap* extension_info_map) { 241 ExtensionInfoMap* extension_info_map) {
179 if (!extension_info_map->IsIncognitoEnabled(extension_id)) 242 if (!extension_info_map->IsIncognitoEnabled(extension_id))
180 return false; 243 return false;
181 244
182 // Only allow incognito toplevel navigations to extension resources in 245 // Only allow incognito toplevel navigations to extension resources in
183 // split mode. In spanning mode, the extension must run in a single process, 246 // split mode. In spanning mode, the extension must run in a single process,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 FilePath bm_resource_path = 378 FilePath bm_resource_path =
316 FilePath().AppendASCII(kComponentExtensionResources[i].name); 379 FilePath().AppendASCII(kComponentExtensionResources[i].name);
317 bm_resource_path = bm_resource_path.NormalizePathSeparators(); 380 bm_resource_path = bm_resource_path.NormalizePathSeparators();
318 if (relative_path == bm_resource_path) { 381 if (relative_path == bm_resource_path) {
319 return new URLRequestResourceBundleJob(request, relative_path, 382 return new URLRequestResourceBundleJob(request, relative_path,
320 kComponentExtensionResources[i].value, content_security_policy, 383 kComponentExtensionResources[i].value, content_security_policy,
321 send_cors_header); 384 send_cors_header);
322 } 385 }
323 } 386 }
324 } 387 }
325 // TODO(tc): Move all of these files into resources.pak so we don't break
326 // when updating on Linux.
327 ExtensionResource resource(extension_id, directory_path,
328 extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
329 388
330 FilePath resource_file_path; 389 return new URLRequestExtensionJob(request, extension_id, directory_path,
331 {
332 // Getting the file path will touch the file system. Fixing
333 // crbug.com/59849 would also fix this. Suppress the error for now.
334 base::ThreadRestrictions::ScopedAllowIO allow_io;
335 resource_file_path = resource.GetFilePath();
336 }
337
338 return new URLRequestExtensionJob(request, resource_file_path,
339 content_security_policy, send_cors_header); 390 content_security_policy, send_cors_header);
340 } 391 }
341 392
342 } // namespace 393 } // namespace
343 394
344 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( 395 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler(
345 bool is_incognito, 396 bool is_incognito,
346 ExtensionInfoMap* extension_info_map) { 397 ExtensionInfoMap* extension_info_map) {
347 return new ExtensionProtocolHandler(is_incognito, extension_info_map); 398 return new ExtensionProtocolHandler(is_incognito, extension_info_map);
348 } 399 }
OLDNEW
« no previous file with comments | « no previous file | content/browser/histogram_internals_request_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698