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

Side by Side Diff: content/browser/renderer_host/buffered_resource_handler.cc

Issue 10332130: Use defer out-params instead of ResourceDispatcherHostImpl::PauseRequest(...true) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
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 "content/browser/renderer_host/buffered_resource_handler.h" 5 #include "content/browser/renderer_host/buffered_resource_handler.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 ResourceHandler* handler, 65 ResourceHandler* handler,
66 ResourceDispatcherHostImpl* host, 66 ResourceDispatcherHostImpl* host,
67 net::URLRequest* request) 67 net::URLRequest* request)
68 : LayeredResourceHandler(handler), 68 : LayeredResourceHandler(handler),
69 host_(host), 69 host_(host),
70 request_(request), 70 request_(request),
71 read_buffer_size_(0), 71 read_buffer_size_(0),
72 bytes_read_(0), 72 bytes_read_(0),
73 sniff_content_(false), 73 sniff_content_(false),
74 wait_for_plugins_(false), 74 wait_for_plugins_(false),
75 deferred_waiting_for_plugins_(false),
75 buffering_(false), 76 buffering_(false),
76 next_handler_needs_response_started_(false), 77 next_handler_needs_response_started_(false),
77 next_handler_needs_will_read_(false), 78 next_handler_needs_will_read_(false),
78 finished_(false) { 79 finished_(false) {
79 } 80 }
80 81
81 bool BufferedResourceHandler::OnResponseStarted( 82 bool BufferedResourceHandler::OnResponseStarted(
82 int request_id, 83 int request_id,
83 ResourceResponse* response) { 84 ResourceResponse* response,
85 bool* defer) {
84 response_ = response; 86 response_ = response;
87
85 if (!DelayResponse()) 88 if (!DelayResponse())
86 return CompleteResponseStarted(request_id); 89 return CompleteResponseStarted(request_id, defer);
90
91 if (wait_for_plugins_) {
92 deferred_waiting_for_plugins_ = true;
93 *defer = true;
94 }
87 return true; 95 return true;
88 } 96 }
89 97
90 void BufferedResourceHandler::OnRequestClosed() { 98 void BufferedResourceHandler::OnRequestClosed() {
91 request_ = NULL; 99 request_ = NULL;
92 next_handler_->OnRequestClosed(); 100 next_handler_->OnRequestClosed();
93 } 101 }
94 102
95 // We'll let the original event handler provide a buffer, and reuse it for 103 // We'll let the original event handler provide a buffer, and reuse it for
96 // subsequent reads until we're done buffering. 104 // subsequent reads until we're done buffering.
97 bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, 105 bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
98 int* buf_size, int min_size) { 106 int* buf_size, int min_size) {
99 if (buffering_) { 107 if (buffering_) {
100 DCHECK(!my_buffer_.get()); 108 DCHECK(!my_buffer_.get());
101 my_buffer_ = new net::IOBuffer(net::kMaxBytesToSniff); 109 my_buffer_ = new net::IOBuffer(net::kMaxBytesToSniff);
102 *buf = my_buffer_.get(); 110 *buf = my_buffer_.get();
103 *buf_size = net::kMaxBytesToSniff; 111 *buf_size = net::kMaxBytesToSniff;
104 return true; 112 return true;
105 } 113 }
106 114
107 if (finished_) 115 if (finished_)
108 return false; 116 return false;
109 117
110 if (!next_handler_->OnWillRead(request_id, buf, buf_size, min_size)) { 118 if (!next_handler_->OnWillRead(request_id, buf, buf_size, min_size))
111 return false; 119 return false;
112 } 120
113 read_buffer_ = *buf; 121 read_buffer_ = *buf;
114 read_buffer_size_ = *buf_size; 122 read_buffer_size_ = *buf_size;
115 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2); 123 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
116 bytes_read_ = 0; 124 bytes_read_ = 0;
117 return true; 125 return true;
118 } 126 }
119 127
120 bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { 128 bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read,
121 ResourceRequestInfoImpl* info = 129 bool* defer) {
122 ResourceRequestInfoImpl::ForRequest(request_);
123
124 if (sniff_content_) { 130 if (sniff_content_) {
125 if (KeepBuffering(*bytes_read)) 131 if (KeepBuffering(*bytes_read)) {
132 if (wait_for_plugins_)
133 *defer = deferred_waiting_for_plugins_ = true;
126 return true; 134 return true;
135 }
127 136
128 *bytes_read = bytes_read_; 137 *bytes_read = bytes_read_;
129 138
130 // Done buffering, send the pending ResponseStarted event. 139 // Done buffering, send the pending ResponseStarted event.
131 if (!CompleteResponseStarted(request_id)) 140 if (!CompleteResponseStarted(request_id, defer))
132 return false; 141 return false;
133 142 if (*defer)
134 // The next handler might have paused the request in OnResponseStarted.
135 if (info->pause_count())
136 return true; 143 return true;
137 } else if (wait_for_plugins_) { 144 } else if (wait_for_plugins_) {
145 *defer = deferred_waiting_for_plugins_ = true;
138 return true; 146 return true;
139 } 147 }
140 148
141 if (!ForwardPendingEventsToNextHandler(request_id)) 149 if (!ForwardPendingEventsToNextHandler(request_id, defer))
142 return false; 150 return false;
143 if (info->pause_count()) 151 if (*defer)
144 return true; 152 return true;
145 153
146 // Release the reference that we acquired at OnWillRead. 154 // Release the reference that we acquired at OnWillRead.
147 read_buffer_ = NULL; 155 read_buffer_ = NULL;
148 return next_handler_->OnReadCompleted(request_id, bytes_read); 156 return next_handler_->OnReadCompleted(request_id, bytes_read, defer);
149 } 157 }
150 158
151 BufferedResourceHandler::~BufferedResourceHandler() {} 159 BufferedResourceHandler::~BufferedResourceHandler() {}
152 160
153 bool BufferedResourceHandler::DelayResponse() { 161 bool BufferedResourceHandler::DelayResponse() {
154 std::string mime_type; 162 std::string mime_type;
155 request_->GetMimeType(&mime_type); 163 request_->GetMimeType(&mime_type);
156 164
157 std::string content_type_options; 165 std::string content_type_options;
158 request_->GetResponseHeaderByName("x-content-type-options", 166 request_->GetResponseHeaderByName("x-content-type-options",
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 244 }
237 245
238 buffering_ = false; 246 buffering_ = false;
239 247
240 if (wait_for_plugins_) 248 if (wait_for_plugins_)
241 return true; 249 return true;
242 250
243 return false; 251 return false;
244 } 252 }
245 253
246 bool BufferedResourceHandler::CompleteResponseStarted(int request_id) { 254 bool BufferedResourceHandler::CompleteResponseStarted(int request_id,
255 bool* defer) {
247 ResourceRequestInfoImpl* info = 256 ResourceRequestInfoImpl* info =
248 ResourceRequestInfoImpl::ForRequest(request_); 257 ResourceRequestInfoImpl::ForRequest(request_);
249 std::string mime_type; 258 std::string mime_type;
250 request_->GetMimeType(&mime_type); 259 request_->GetMimeType(&mime_type);
251 260
252 // Check if this is an X.509 certificate, if yes, let it be handled
253 // by X509UserCertResourceHandler.
254 if (mime_type == "application/x-x509-user-cert") { 261 if (mime_type == "application/x-x509-user-cert") {
255 // This is entirely similar to how DownloadResourceThrottle works except we 262 // Let X.509 certs be handled by the X509UserCertResourceHandler.
263
264 // This is entirely similar to how DownloadResourceHandler works except we
256 // are doing it for an X.509 client certificates. 265 // are doing it for an X.509 client certificates.
257 // TODO(darin): This does not belong here! 266 // TODO(darin): This does not belong here!
258 267
259 if (response_->headers && // Can be NULL if FTP. 268 if (response_->headers && // Can be NULL if FTP.
260 response_->headers->response_code() / 100 != 2) { 269 response_->headers->response_code() / 100 != 2) {
261 // The response code indicates that this is an error page, but we are 270 // The response code indicates that this is an error page, but we are
262 // expecting an X.509 user certificate. We follow Firefox here and show 271 // expecting an X.509 user certificate. We follow Firefox here and show
263 // our own error page instead of handling the error page as a 272 // our own error page instead of handling the error page as a
264 // certificate. 273 // certificate.
265 // TODO(abarth): We should abstract the response_code test, but this kind 274 // TODO(abarth): We should abstract the response_code test, but this kind
266 // of check is scattered throughout our codebase. 275 // of check is scattered throughout our codebase.
267 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); 276 request_->CancelWithError(net::ERR_FILE_NOT_FOUND);
268 return false; 277 return false;
269 } 278 }
270 279
271 X509UserCertResourceHandler* x509_cert_handler = 280 X509UserCertResourceHandler* x509_cert_handler =
272 new X509UserCertResourceHandler(request_, 281 new X509UserCertResourceHandler(request_,
273 info->GetChildID(), 282 info->GetChildID(),
274 info->GetRouteID()); 283 info->GetRouteID());
275 if (!UseAlternateResourceHandler(request_id, x509_cert_handler)) 284 if (!UseAlternateResourceHandler(request_id, x509_cert_handler, defer))
276 return false; 285 return false;
277 } 286 } else if (info->allow_download() && ShouldDownload(NULL)) {
287 // Forward the data to the download thread.
278 288
279 // Check to see if we should forward the data from this request to the
280 // download thread.
281 // TODO(paulg): Only download if the context from the renderer allows it.
282 if (info->allow_download() && ShouldDownload(NULL)) {
283 if (response_->headers && // Can be NULL if FTP. 289 if (response_->headers && // Can be NULL if FTP.
284 response_->headers->response_code() / 100 != 2) { 290 response_->headers->response_code() / 100 != 2) {
285 // The response code indicates that this is an error page, but we don't 291 // The response code indicates that this is an error page, but we don't
286 // know how to display the content. We follow Firefox here and show our 292 // know how to display the content. We follow Firefox here and show our
287 // own error page instead of triggering a download. 293 // own error page instead of triggering a download.
288 // TODO(abarth): We should abstract the response_code test, but this kind 294 // TODO(abarth): We should abstract the response_code test, but this kind
289 // of check is scattered throughout our codebase. 295 // of check is scattered throughout our codebase.
290 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); 296 request_->CancelWithError(net::ERR_FILE_NOT_FOUND);
291 return false; 297 return false;
292 } 298 }
293 299
294 info->set_is_download(true); 300 info->set_is_download(true);
295 301
296 scoped_refptr<ResourceHandler> handler( 302 scoped_refptr<ResourceHandler> handler(
297 host_->CreateResourceHandlerForDownload( 303 host_->CreateResourceHandlerForDownload(
298 request_, 304 request_,
299 info->GetContext(), 305 info->GetContext(),
300 info->GetChildID(), 306 info->GetChildID(),
301 info->GetRouteID(), 307 info->GetRouteID(),
302 info->GetRequestID(), 308 info->GetRequestID(),
303 true, // is_content_initiated 309 true, // is_content_initiated
304 DownloadSaveInfo(), 310 DownloadSaveInfo(),
305 DownloadResourceHandler::OnStartedCallback())); 311 DownloadResourceHandler::OnStartedCallback()));
306 312
307 if (!UseAlternateResourceHandler(request_id, handler)) 313 if (!UseAlternateResourceHandler(request_id, handler, defer))
308 return false; 314 return false;
309 } 315 }
310 316
311 if (info->pause_count()) 317 if (*defer)
312 return true; 318 return true;
313 319
314 return next_handler_->OnResponseStarted(request_id, response_); 320 return next_handler_->OnResponseStarted(request_id, response_, defer);
315 } 321 }
316 322
317 bool BufferedResourceHandler::ShouldWaitForPlugins() { 323 bool BufferedResourceHandler::ShouldWaitForPlugins() {
318 bool need_plugin_list; 324 bool need_plugin_list;
319 if (!ShouldDownload(&need_plugin_list) || !need_plugin_list) 325 if (!ShouldDownload(&need_plugin_list) || !need_plugin_list)
320 return false; 326 return false;
321 327
322 // We don't want to keep buffering as our buffer will fill up.
323 ResourceRequestInfoImpl* info =
324 ResourceRequestInfoImpl::ForRequest(request_);
325 host_->PauseRequest(info->GetChildID(), info->GetRequestID(), true);
326
327 // Get the plugins asynchronously. 328 // Get the plugins asynchronously.
328 PluginServiceImpl::GetInstance()->GetPlugins( 329 PluginServiceImpl::GetInstance()->GetPlugins(
329 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, this)); 330 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, this));
330 return true; 331 return true;
331 } 332 }
332 333
333 // This test mirrors the decision that WebKit makes in 334 // This test mirrors the decision that WebKit makes in
334 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. 335 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType.
335 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) { 336 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) {
336 if (need_plugin_list) 337 if (need_plugin_list)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 } 373 }
373 } else { 374 } else {
374 DCHECK(!stale); 375 DCHECK(!stale);
375 } 376 }
376 377
377 return !found; 378 return !found;
378 } 379 }
379 380
380 bool BufferedResourceHandler::UseAlternateResourceHandler( 381 bool BufferedResourceHandler::UseAlternateResourceHandler(
381 int request_id, 382 int request_id,
382 ResourceHandler* handler) { 383 ResourceHandler* handler,
384 bool* defer) {
383 // Inform the original ResourceHandler that this will be handled entirely by 385 // Inform the original ResourceHandler that this will be handled entirely by
384 // the new ResourceHandler. 386 // the new ResourceHandler.
385 // TODO(darin): We should probably check the return values of these. 387 // TODO(darin): We should probably check the return values of these.
386 next_handler_->OnResponseStarted(request_id, response_); 388 bool defer_ignored = false;
389 next_handler_->OnResponseStarted(request_id, response_, &defer_ignored);
390 DCHECK(!defer_ignored);
387 net::URLRequestStatus status(net::URLRequestStatus::HANDLED_EXTERNALLY, 0); 391 net::URLRequestStatus status(net::URLRequestStatus::HANDLED_EXTERNALLY, 0);
388 next_handler_->OnResponseCompleted(request_id, status, std::string()); 392 next_handler_->OnResponseCompleted(request_id, status, std::string());
389 393
390 // Remove the non-owning pointer to the CrossSiteResourceHandler, if any, 394 // Remove the non-owning pointer to the CrossSiteResourceHandler, if any,
391 // from the extra request info because the CrossSiteResourceHandler (part of 395 // from the extra request info because the CrossSiteResourceHandler (part of
392 // the original ResourceHandler chain) will be deleted by the next statement. 396 // the original ResourceHandler chain) will be deleted by the next statement.
393 ResourceRequestInfoImpl* info = 397 ResourceRequestInfoImpl* info =
394 ResourceRequestInfoImpl::ForRequest(request_); 398 ResourceRequestInfoImpl::ForRequest(request_);
395 info->set_cross_site_handler(NULL); 399 info->set_cross_site_handler(NULL);
396 400
397 // This is handled entirely within the new ResourceHandler, so just reset the 401 // This is handled entirely within the new ResourceHandler, so just reset the
398 // original ResourceHandler. 402 // original ResourceHandler.
399 next_handler_ = handler; 403 next_handler_ = handler;
400 404
401 next_handler_needs_response_started_ = true; 405 next_handler_needs_response_started_ = true;
402 next_handler_needs_will_read_ = true; 406 next_handler_needs_will_read_ = true;
403 407
404 return ForwardPendingEventsToNextHandler(request_id); 408 return ForwardPendingEventsToNextHandler(request_id, defer);
405 } 409 }
406 410
407 bool BufferedResourceHandler::ForwardPendingEventsToNextHandler( 411 bool BufferedResourceHandler::ForwardPendingEventsToNextHandler(int request_id,
408 int request_id) { 412 bool* defer) {
409 ResourceRequestInfoImpl* info =
410 ResourceRequestInfoImpl::ForRequest(request_);
411 if (info->pause_count())
412 return true;
413
414 if (next_handler_needs_response_started_) { 413 if (next_handler_needs_response_started_) {
415 if (!next_handler_->OnResponseStarted(request_id, response_)) 414 if (!next_handler_->OnResponseStarted(request_id, response_, defer))
416 return false; 415 return false;
417 // If the request was paused during OnResponseStarted, we need to avoid 416 // If the request was deferred during OnResponseStarted, we need to avoid
418 // calling OnResponseStarted again. 417 // calling OnResponseStarted again.
419 next_handler_needs_response_started_ = false; 418 next_handler_needs_response_started_ = false;
420 if (info->pause_count()) 419 if (*defer)
421 return true; 420 return true;
422 } 421 }
423 422
424 if (next_handler_needs_will_read_) { 423 if (next_handler_needs_will_read_) {
425 CopyReadBufferToNextHandler(request_id); 424 CopyReadBufferToNextHandler(request_id);
426 // If the request was paused during OnWillRead, we need to be sure to try
427 // calling OnWillRead again.
428 if (info->pause_count())
429 return true;
430 next_handler_needs_will_read_ = false; 425 next_handler_needs_will_read_ = false;
431 } 426 }
432 return true; 427 return true;
433 } 428 }
434 429
435 void BufferedResourceHandler::CopyReadBufferToNextHandler(int request_id) { 430 void BufferedResourceHandler::CopyReadBufferToNextHandler(int request_id) {
436 if (!bytes_read_) 431 if (!bytes_read_)
437 return; 432 return;
438 433
439 net::IOBuffer* buf = NULL; 434 net::IOBuffer* buf = NULL;
440 int buf_len = 0; 435 int buf_len = 0;
441 if (next_handler_->OnWillRead(request_id, &buf, &buf_len, bytes_read_)) { 436 if (next_handler_->OnWillRead(request_id, &buf, &buf_len, bytes_read_)) {
442 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); 437 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0));
443 memcpy(buf->data(), read_buffer_->data(), bytes_read_); 438 memcpy(buf->data(), read_buffer_->data(), bytes_read_);
444 } 439 }
445 } 440 }
446 441
447 void BufferedResourceHandler::OnPluginsLoaded( 442 void BufferedResourceHandler::OnPluginsLoaded(
448 const std::vector<webkit::WebPluginInfo>& plugins) { 443 const std::vector<webkit::WebPluginInfo>& plugins) {
444 bool needs_resume = deferred_waiting_for_plugins_;
445 deferred_waiting_for_plugins_ = false;
446
449 wait_for_plugins_ = false; 447 wait_for_plugins_ = false;
450 if (!request_) 448 if (!request_)
451 return; 449 return;
452 450
453 ResourceRequestInfoImpl* info = 451 ResourceRequestInfoImpl* info =
454 ResourceRequestInfoImpl::ForRequest(request_); 452 ResourceRequestInfoImpl::ForRequest(request_);
455 int child_id = info->GetChildID(); 453 int child_id = info->GetChildID();
456 int request_id = info->GetRequestID(); 454 int request_id = info->GetRequestID();
457 455
458 host_->PauseRequest(child_id, request_id, false); 456 bool defer = false;
459 if (!CompleteResponseStarted(request_id)) 457 if (!CompleteResponseStarted(request_id, &defer)) {
460 host_->CancelRequest(child_id, request_id, false); 458 host_->CancelRequest(child_id, request_id, false);
459 } else if (!defer && needs_resume) {
460 host_->ResumeDeferredRequest(child_id, request_id);
461 }
461 } 462 }
462 463
463 } // namespace content 464 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/buffered_resource_handler.h ('k') | content/browser/renderer_host/cross_site_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698