| 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 "content/browser/loader/mime_sniffing_resource_handler.h" | 5 #include "content/browser/loader/mime_sniffing_resource_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 } | 269 } |
| 270 } | 270 } |
| 271 | 271 |
| 272 bool MimeSniffingResourceHandler::ProcessState(bool* defer) { | 272 bool MimeSniffingResourceHandler::ProcessState(bool* defer) { |
| 273 bool return_value = true; | 273 bool return_value = true; |
| 274 while (!*defer && return_value && state_ != STATE_STREAMING) { | 274 while (!*defer && return_value && state_ != STATE_STREAMING) { |
| 275 switch (state_) { | 275 switch (state_) { |
| 276 case STATE_BUFFERING: | 276 case STATE_BUFFERING: |
| 277 return_value = MaybeIntercept(defer); | 277 return_value = MaybeIntercept(defer); |
| 278 break; | 278 break; |
| 279 case STATE_INTERCEPTION_CHECK_DONE: | 279 case STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER: |
| 280 return_value = ReplayResponseReceived(defer); | 280 return_value = PrepareToUseNewHandler(defer); |
| 281 break; | 281 break; |
| 282 case STATE_REPLAYING_RESPONSE_RECEIVED: | 282 case STATE_PREPARING_TO_USE_NEW_HANDLER: |
| 283 return_value = ReplayReceivedResponse(defer); |
| 284 break; |
| 285 case STATE_REPLAYING_RECEIVED_RESPONSE: |
| 283 return_value = ReplayReadCompleted(defer); | 286 return_value = ReplayReadCompleted(defer); |
| 284 break; | 287 break; |
| 285 default: | 288 default: |
| 286 NOTREACHED(); | 289 NOTREACHED(); |
| 287 break; | 290 break; |
| 288 } | 291 } |
| 289 } | 292 } |
| 290 return return_value; | 293 return return_value; |
| 291 } | 294 } |
| 292 | 295 |
| 293 bool MimeSniffingResourceHandler::MaybeIntercept(bool* defer) { | 296 bool MimeSniffingResourceHandler::MaybeIntercept(bool* defer) { |
| 294 DCHECK_EQ(STATE_BUFFERING, state_); | 297 DCHECK_EQ(STATE_BUFFERING, state_); |
| 295 // If a request that can be intercepted failed the check for interception | 298 // If a request that can be intercepted failed the check for interception |
| 296 // step, it should be canceled. | 299 // step, it should be canceled. |
| 297 if (!MaybeStartInterception(defer)) | 300 if (!MaybeStartInterception(defer)) |
| 298 return false; | 301 return false; |
| 299 | 302 |
| 300 if (!*defer) | 303 if (!*defer) |
| 301 state_ = STATE_INTERCEPTION_CHECK_DONE; | 304 state_ = STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER; |
| 302 | 305 |
| 303 return true; | 306 return true; |
| 304 } | 307 } |
| 305 | 308 |
| 306 bool MimeSniffingResourceHandler::ReplayResponseReceived(bool* defer) { | 309 bool MimeSniffingResourceHandler::PrepareToUseNewHandler(bool* defer) { |
| 307 DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_); | 310 DCHECK_EQ(STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER, state_); |
| 308 state_ = STATE_REPLAYING_RESPONSE_RECEIVED; | 311 state_ = STATE_PREPARING_TO_USE_NEW_HANDLER; |
| 312 if (!new_handler_) |
| 313 return true; |
| 314 |
| 315 // The InterceptingResourceHandler's OnWillStart method has already been |
| 316 // called, so need to call it on the new ResourceHandler before it can be |
| 317 // swapped in to take its place. Redirects will not be passed to the new |
| 318 // handler. |
| 319 // TODO(mmenke): If the request is cancelled while new_handler_ is |
| 320 // non-NULL, the new handler will not get an OnResponseCompleted call |
| 321 // before being deleted. Is that worth fixing? |
| 322 |
| 323 // Temporarily set NewHandler's ResourceController, so it can cancel / |
| 324 // pause / resume the request, if needed. It ultimately should use |
| 325 // InterceptingHandler's ResourceController, but if cancels the request, |
| 326 // it shouldn't go through that ResourceController, as it would be |
| 327 // calling into the controller when the controller may not think the |
| 328 // ball is currently in its court. |
| 329 new_handler_->SetController(this); |
| 330 |
| 331 return new_handler_->OnWillStart(request()->url(), defer); |
| 332 } |
| 333 |
| 334 bool MimeSniffingResourceHandler::ReplayReceivedResponse(bool* defer) { |
| 335 DCHECK_EQ(STATE_PREPARING_TO_USE_NEW_HANDLER, state_); |
| 336 |
| 337 // Swap in new handler, if there is one. |
| 338 if (new_handler_) { |
| 339 // Clear the controller. |
| 340 new_handler_->SetController(nullptr); |
| 341 |
| 342 intercepting_handler_->UseNewHandler(std::move(new_handler_), |
| 343 std::move(payload_for_old_handler_)); |
| 344 } |
| 345 |
| 346 state_ = STATE_REPLAYING_RECEIVED_RESPONSE; |
| 309 return next_handler_->OnResponseStarted(response_.get(), defer); | 347 return next_handler_->OnResponseStarted(response_.get(), defer); |
| 310 } | 348 } |
| 311 | 349 |
| 312 bool MimeSniffingResourceHandler::ReplayReadCompleted(bool* defer) { | 350 bool MimeSniffingResourceHandler::ReplayReadCompleted(bool* defer) { |
| 313 DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_); | 351 DCHECK_EQ(STATE_REPLAYING_RECEIVED_RESPONSE, state_); |
| 314 | 352 |
| 315 state_ = STATE_STREAMING; | 353 state_ = STATE_STREAMING; |
| 316 | 354 |
| 317 if (!read_buffer_.get()) | 355 if (!read_buffer_.get()) |
| 318 return true; | 356 return true; |
| 319 | 357 |
| 320 bool result = next_handler_->OnReadCompleted(bytes_read_, defer); | 358 bool result = next_handler_->OnReadCompleted(bytes_read_, defer); |
| 321 | 359 |
| 322 read_buffer_ = nullptr; | 360 read_buffer_ = nullptr; |
| 323 read_buffer_size_ = 0; | 361 read_buffer_size_ = 0; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 if (handled_by_plugin || *defer) | 442 if (handled_by_plugin || *defer) |
| 405 return true; | 443 return true; |
| 406 } | 444 } |
| 407 | 445 |
| 408 // This is request is a download, | 446 // This is request is a download, |
| 409 | 447 |
| 410 if (!CheckResponseIsNotProvisional()) | 448 if (!CheckResponseIsNotProvisional()) |
| 411 return false; | 449 return false; |
| 412 | 450 |
| 413 info->set_is_download(true); | 451 info->set_is_download(true); |
| 414 std::unique_ptr<ResourceHandler> handler( | 452 new_handler_ = |
| 415 host_->CreateResourceHandlerForDownload(request(), | 453 host_->CreateResourceHandlerForDownload(request(), |
| 416 true, // is_content_initiated | 454 true, // is_content_initiated |
| 417 must_download)); | 455 must_download); |
| 418 intercepting_handler_->UseNewHandler(std::move(handler), std::string()); | |
| 419 return true; | 456 return true; |
| 420 } | 457 } |
| 421 | 458 |
| 422 bool MimeSniffingResourceHandler::CheckForPluginHandler( | 459 bool MimeSniffingResourceHandler::CheckForPluginHandler( |
| 423 bool* defer, | 460 bool* defer, |
| 424 bool* handled_by_plugin) { | 461 bool* handled_by_plugin) { |
| 425 *handled_by_plugin = false; | 462 *handled_by_plugin = false; |
| 426 #if defined(ENABLE_PLUGINS) | 463 #if defined(ENABLE_PLUGINS) |
| 427 ResourceRequestInfoImpl* info = GetRequestInfo(); | 464 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 428 bool allow_wildcard = false; | 465 bool allow_wildcard = false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 445 | 482 |
| 446 if (has_plugin && plugin.type != WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) { | 483 if (has_plugin && plugin.type != WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) { |
| 447 *handled_by_plugin = true; | 484 *handled_by_plugin = true; |
| 448 return true; | 485 return true; |
| 449 } | 486 } |
| 450 | 487 |
| 451 // Attempt to intercept the request as a stream. | 488 // Attempt to intercept the request as a stream. |
| 452 base::FilePath plugin_path; | 489 base::FilePath plugin_path; |
| 453 if (has_plugin) | 490 if (has_plugin) |
| 454 plugin_path = plugin.path; | 491 plugin_path = plugin.path; |
| 455 std::string payload; | 492 new_handler_ = host_->MaybeInterceptAsStream( |
| 456 std::unique_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( | 493 plugin_path, request(), response_.get(), &payload_for_old_handler_); |
| 457 plugin_path, request(), response_.get(), &payload)); | 494 if (new_handler_) { |
| 458 if (handler) { | |
| 459 if (!CheckResponseIsNotProvisional()) | 495 if (!CheckResponseIsNotProvisional()) |
| 460 return false; | 496 return false; |
| 461 *handled_by_plugin = true; | 497 *handled_by_plugin = true; |
| 462 intercepting_handler_->UseNewHandler(std::move(handler), payload); | |
| 463 } | 498 } |
| 464 #endif | 499 #endif |
| 465 return true; | 500 return true; |
| 466 } | 501 } |
| 467 | 502 |
| 468 bool MimeSniffingResourceHandler::CanBeIntercepted() { | 503 bool MimeSniffingResourceHandler::CanBeIntercepted() { |
| 469 if (response_->head.headers.get() && | 504 if (response_->head.headers.get() && |
| 470 response_->head.headers->response_code() == 304) { | 505 response_->head.headers->response_code() == 304) { |
| 471 return false; | 506 return false; |
| 472 } | 507 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 549 |
| 515 void MimeSniffingResourceHandler::OnPluginsLoaded( | 550 void MimeSniffingResourceHandler::OnPluginsLoaded( |
| 516 const std::vector<WebPluginInfo>& plugins) { | 551 const std::vector<WebPluginInfo>& plugins) { |
| 517 // No longer blocking on the plugins being loaded. | 552 // No longer blocking on the plugins being loaded. |
| 518 request()->LogUnblocked(); | 553 request()->LogUnblocked(); |
| 519 if (state_ == STATE_BUFFERING) | 554 if (state_ == STATE_BUFFERING) |
| 520 AdvanceState(); | 555 AdvanceState(); |
| 521 } | 556 } |
| 522 | 557 |
| 523 } // namespace content | 558 } // namespace content |
| OLD | NEW |