Chromium Code Reviews| 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/buffered_resource_handler.h" | 5 #include "content/browser/loader/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/location.h" | 10 #include "base/location.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 type_hint, &new_type); | 287 type_hint, &new_type); |
| 288 | 288 |
| 289 // SniffMimeType() returns false if there is not enough data to determine | 289 // SniffMimeType() returns false if there is not enough data to determine |
| 290 // the mime type. However, even if it returns false, it returns a new type | 290 // the mime type. However, even if it returns false, it returns a new type |
| 291 // that is probably better than the current one. | 291 // that is probably better than the current one. |
| 292 response_->head.mime_type.assign(new_type); | 292 response_->head.mime_type.assign(new_type); |
| 293 | 293 |
| 294 return made_final_decision; | 294 return made_final_decision; |
| 295 } | 295 } |
| 296 | 296 |
| 297 bool BufferedResourceHandler::IsHandledByPlugin(bool* defer, | |
| 298 bool* request_handled) { | |
| 299 #if defined(ENABLE_PLUGINS) | |
| 300 bool stale; | |
| 301 WebPluginInfo plugin; | |
| 302 bool allow_wildcard = false; | |
| 303 ResourceRequestInfoImpl* info = GetRequestInfo(); | |
| 304 bool has_plugin = plugin_service_->GetPluginInfo( | |
| 305 info->GetChildID(), info->GetRenderFrameID(), info->GetContext(), | |
| 306 request()->url(), GURL(), response_->head.mime_type, allow_wildcard, | |
| 307 &stale, &plugin, NULL); | |
| 308 | |
| 309 if (stale) { | |
| 310 // Refresh the plugins asynchronously. | |
| 311 plugin_service_->GetPlugins( | |
| 312 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, | |
| 313 weak_ptr_factory_.GetWeakPtr())); | |
| 314 request()->LogBlockedBy("BufferedResourceHandler"); | |
| 315 *defer = true; | |
| 316 return true; | |
| 317 } | |
| 318 | |
| 319 if (has_plugin) { | |
| 320 if (plugin.type == WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) { | |
| 321 // If it is a MimeHandlerView plugin, intercept the stream. | |
| 322 std::string payload; | |
| 323 scoped_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( | |
| 324 plugin.path, request(), response_.get(), &payload)); | |
|
mmenke
2015/06/11 19:38:04
This exactly matches the fallthrough logic. Maybe
raymes
2015/07/01 05:13:18
That's much simpler, thanks!
| |
| 325 if (handler) { | |
| 326 *request_handled = UseAlternateNextHandler(handler.Pass(), payload); | |
| 327 return true; | |
| 328 } | |
| 329 // If the plugin is a MimeHandlerView plugin it should always be | |
| 330 // intercepted as a stream so this point should never be reached. | |
|
mmenke
2015/06/11 19:38:04
This is content/, not chrome/. I assume MimeHandl
raymes
2015/07/01 05:13:18
Done.
| |
| 331 NOTREACHED(); | |
| 332 return false; | |
| 333 } else { | |
| 334 return true; | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 // If execution reaches here then try intercepting the stream for the old | |
| 339 // streamsPrivate extensions API. This API is deprecated and should go away. | |
|
mmenke
2015/06/11 19:38:04
The streamsPrivate API is a chrome feature. We're
raymes
2015/07/01 05:13:18
Done.
| |
| 340 std::string payload; | |
| 341 scoped_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( | |
| 342 base::FilePath(), request(), response_.get(), &payload)); | |
| 343 if (handler) { | |
| 344 *request_handled = UseAlternateNextHandler(handler.Pass(), payload); | |
| 345 return true; | |
| 346 } | |
| 347 #endif | |
| 348 return false; | |
| 349 } | |
| 350 | |
| 297 bool BufferedResourceHandler::SelectNextHandler(bool* defer) { | 351 bool BufferedResourceHandler::SelectNextHandler(bool* defer) { |
| 298 DCHECK(!response_->head.mime_type.empty()); | 352 DCHECK(!response_->head.mime_type.empty()); |
| 299 | 353 |
| 300 ResourceRequestInfoImpl* info = GetRequestInfo(); | 354 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 301 const std::string& mime_type = response_->head.mime_type; | 355 const std::string& mime_type = response_->head.mime_type; |
| 302 | 356 |
| 303 if (mime_util::IsSupportedCertificateMimeType(mime_type)) { | 357 if (mime_util::IsSupportedCertificateMimeType(mime_type)) { |
| 304 // Install certificate file. | 358 // Install certificate file. |
| 305 info->set_is_download(true); | 359 info->set_is_download(true); |
| 306 scoped_ptr<ResourceHandler> handler( | 360 scoped_ptr<ResourceHandler> handler( |
| 307 new CertificateResourceHandler(request())); | 361 new CertificateResourceHandler(request())); |
| 308 return UseAlternateNextHandler(handler.Pass(), std::string()); | 362 return UseAlternateNextHandler(handler.Pass(), std::string()); |
| 309 } | 363 } |
| 310 | 364 |
| 311 // Allow requests for object/embed tags to be intercepted as streams. | 365 // Allow requests for object/embed tags to be intercepted as streams. |
| 312 if (info->GetResourceType() == content::RESOURCE_TYPE_OBJECT) { | 366 if (info->GetResourceType() == content::RESOURCE_TYPE_OBJECT) { |
| 313 DCHECK(!info->allow_download()); | 367 DCHECK(!info->allow_download()); |
| 314 std::string payload; | 368 |
| 315 scoped_ptr<ResourceHandler> handler( | 369 bool request_handled = true; |
| 316 host_->MaybeInterceptAsStream(request(), response_.get(), &payload)); | 370 bool handled_by_plugin = IsHandledByPlugin(defer, &request_handled); |
| 317 if (handler) { | 371 if (!request_handled) |
| 318 DCHECK(!mime_util::IsSupportedMimeType(mime_type)); | 372 return false; |
| 319 return UseAlternateNextHandler(handler.Pass(), payload); | 373 if (handled_by_plugin) |
|
mmenke
2015/06/11 19:38:04
If |defer| is set to true, the method also must re
raymes
2015/07/01 05:13:18
Done.
| |
| 320 } | 374 return true; |
| 321 } | 375 } |
| 322 | 376 |
| 323 if (!info->allow_download()) | 377 if (!info->allow_download()) |
| 324 return true; | 378 return true; |
| 325 | 379 |
| 326 // info->allow_download() == true implies | 380 // info->allow_download() == true implies |
| 327 // info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME or | 381 // info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME or |
| 328 // info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME. | 382 // info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME. |
| 329 DCHECK(info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME || | 383 DCHECK(info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME || |
| 330 info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME); | 384 info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME); |
| 331 | 385 |
| 332 bool must_download = MustDownload(); | 386 bool must_download = MustDownload(); |
| 333 if (!must_download) { | 387 if (!must_download) { |
| 334 if (mime_util::IsSupportedMimeType(mime_type)) | 388 if (mime_util::IsSupportedMimeType(mime_type)) |
| 335 return true; | 389 return true; |
| 336 | 390 |
| 337 std::string payload; | 391 bool request_handled = true; |
| 338 scoped_ptr<ResourceHandler> handler( | 392 bool handled_by_plugin = IsHandledByPlugin(defer, &request_handled); |
| 339 host_->MaybeInterceptAsStream(request(), response_.get(), &payload)); | 393 if (!request_handled) |
| 340 if (handler) { | 394 return false; |
| 341 return UseAlternateNextHandler(handler.Pass(), payload); | 395 if (handled_by_plugin) |
| 342 } | |
| 343 | |
| 344 #if defined(ENABLE_PLUGINS) | |
| 345 bool stale; | |
| 346 bool has_plugin = HasSupportingPlugin(&stale); | |
| 347 if (stale) { | |
| 348 // Refresh the plugins asynchronously. | |
| 349 plugin_service_->GetPlugins( | |
| 350 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, | |
| 351 weak_ptr_factory_.GetWeakPtr())); | |
| 352 request()->LogBlockedBy("BufferedResourceHandler"); | |
| 353 *defer = true; | |
| 354 return true; | 396 return true; |
| 355 } | |
| 356 if (has_plugin) | |
| 357 return true; | |
| 358 #endif | |
| 359 } | 397 } |
| 360 | 398 |
| 361 // Install download handler | 399 // Install download handler |
| 362 info->set_is_download(true); | 400 info->set_is_download(true); |
| 363 scoped_ptr<ResourceHandler> handler( | 401 scoped_ptr<ResourceHandler> handler( |
| 364 host_->CreateResourceHandlerForDownload( | 402 host_->CreateResourceHandlerForDownload( |
| 365 request(), | 403 request(), |
| 366 true, // is_content_initiated | 404 true, // is_content_initiated |
| 367 must_download, | 405 must_download, |
| 368 DownloadItem::kInvalidId, | 406 DownloadItem::kInvalidId, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 465 host_->delegate()->ShouldForceDownloadResource( | 503 host_->delegate()->ShouldForceDownloadResource( |
| 466 request()->url(), response_->head.mime_type)) { | 504 request()->url(), response_->head.mime_type)) { |
| 467 must_download_ = true; | 505 must_download_ = true; |
| 468 } else { | 506 } else { |
| 469 must_download_ = false; | 507 must_download_ = false; |
| 470 } | 508 } |
| 471 | 509 |
| 472 return must_download_; | 510 return must_download_; |
| 473 } | 511 } |
| 474 | 512 |
| 475 bool BufferedResourceHandler::HasSupportingPlugin(bool* stale) { | |
| 476 #if defined(ENABLE_PLUGINS) | |
| 477 ResourceRequestInfoImpl* info = GetRequestInfo(); | |
| 478 | |
| 479 bool allow_wildcard = false; | |
| 480 WebPluginInfo plugin; | |
| 481 return plugin_service_->GetPluginInfo( | |
| 482 info->GetChildID(), info->GetRenderFrameID(), info->GetContext(), | |
| 483 request()->url(), GURL(), response_->head.mime_type, allow_wildcard, | |
| 484 stale, &plugin, NULL); | |
| 485 #else | |
| 486 if (stale) | |
| 487 *stale = false; | |
| 488 return false; | |
| 489 #endif | |
| 490 } | |
| 491 | |
| 492 bool BufferedResourceHandler::CopyReadBufferToNextHandler() { | 513 bool BufferedResourceHandler::CopyReadBufferToNextHandler() { |
| 493 if (!read_buffer_.get()) | 514 if (!read_buffer_.get()) |
| 494 return true; | 515 return true; |
| 495 | 516 |
| 496 scoped_refptr<net::IOBuffer> buf; | 517 scoped_refptr<net::IOBuffer> buf; |
| 497 int buf_len = 0; | 518 int buf_len = 0; |
| 498 if (!next_handler_->OnWillRead(&buf, &buf_len, bytes_read_)) | 519 if (!next_handler_->OnWillRead(&buf, &buf_len, bytes_read_)) |
| 499 return false; | 520 return false; |
| 500 | 521 |
| 501 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); | 522 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); |
| 502 memcpy(buf->data(), read_buffer_->data(), bytes_read_); | 523 memcpy(buf->data(), read_buffer_->data(), bytes_read_); |
| 503 return true; | 524 return true; |
| 504 } | 525 } |
| 505 | 526 |
| 506 void BufferedResourceHandler::OnPluginsLoaded( | 527 void BufferedResourceHandler::OnPluginsLoaded( |
| 507 const std::vector<WebPluginInfo>& plugins) { | 528 const std::vector<WebPluginInfo>& plugins) { |
| 508 request()->LogUnblocked(); | 529 request()->LogUnblocked(); |
| 509 bool defer = false; | 530 bool defer = false; |
| 510 if (!ProcessResponse(&defer)) { | 531 if (!ProcessResponse(&defer)) { |
| 511 controller()->Cancel(); | 532 controller()->Cancel(); |
| 512 } else if (!defer) { | 533 } else if (!defer) { |
| 513 controller()->Resume(); | 534 controller()->Resume(); |
| 514 } | 535 } |
| 515 } | 536 } |
| 516 | 537 |
| 517 } // namespace content | 538 } // namespace content |
| OLD | NEW |