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

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

Issue 263513004: Forward MIME types to BrowserPlugin when a viewer is specified. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review fixes Created 6 years, 6 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/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/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "content/browser/download/download_resource_handler.h" 13 #include "content/browser/download/download_resource_handler.h"
14 #include "content/browser/download/download_stats.h" 14 #include "content/browser/download/download_stats.h"
15 #include "content/browser/loader/certificate_resource_handler.h" 15 #include "content/browser/loader/certificate_resource_handler.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h" 16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
17 #include "content/browser/loader/resource_request_info_impl.h" 17 #include "content/browser/loader/resource_request_info_impl.h"
18 #include "content/browser/loader/stream_resource_handler.h"
18 #include "content/browser/plugin_service_impl.h" 19 #include "content/browser/plugin_service_impl.h"
19 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/browser/content_browser_client.h"
20 #include "content/public/browser/download_item.h" 21 #include "content/public/browser/download_item.h"
21 #include "content/public/browser/download_save_info.h" 22 #include "content/public/browser/download_save_info.h"
22 #include "content/public/browser/download_url_parameters.h" 23 #include "content/public/browser/download_url_parameters.h"
23 #include "content/public/browser/resource_context.h" 24 #include "content/public/browser/resource_context.h"
24 #include "content/public/browser/resource_dispatcher_host_delegate.h" 25 #include "content/public/browser/resource_dispatcher_host_delegate.h"
25 #include "content/public/common/resource_response.h" 26 #include "content/public/common/resource_response.h"
26 #include "content/public/common/webplugininfo.h" 27 #include "content/public/common/webplugininfo.h"
27 #include "net/base/io_buffer.h" 28 #include "net/base/io_buffer.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 DCHECK(!response_->head.mime_type.empty()); 304 DCHECK(!response_->head.mime_type.empty());
304 305
305 ResourceRequestInfoImpl* info = GetRequestInfo(); 306 ResourceRequestInfoImpl* info = GetRequestInfo();
306 const std::string& mime_type = response_->head.mime_type; 307 const std::string& mime_type = response_->head.mime_type;
307 308
308 if (net::IsSupportedCertificateMimeType(mime_type)) { 309 if (net::IsSupportedCertificateMimeType(mime_type)) {
309 // Install certificate file. 310 // Install certificate file.
310 info->set_is_download(true); 311 info->set_is_download(true);
311 scoped_ptr<ResourceHandler> handler( 312 scoped_ptr<ResourceHandler> handler(
312 new CertificateResourceHandler(request())); 313 new CertificateResourceHandler(request()));
313 return UseAlternateNextHandler(handler.Pass()); 314 return UseAlternateNextHandler(handler.Pass(), std::string());
314 } 315 }
315 316
316 if (!info->allow_download()) 317 if (!info->allow_download())
317 return true; 318 return true;
318 319
319 bool must_download = MustDownload(); 320 bool must_download = MustDownload();
320 if (!must_download) { 321 if (!must_download) {
321 if (net::IsSupportedMimeType(mime_type)) 322 if (net::IsSupportedMimeType(mime_type))
322 return true; 323 return true;
323 324
325 std::string payload;
324 scoped_ptr<ResourceHandler> handler( 326 scoped_ptr<ResourceHandler> handler(
325 host_->MaybeInterceptAsStream(request(), response_.get())); 327 host_->MaybeInterceptAsStream(request(), response_.get(), &payload));
326 if (handler) 328 if (handler) {
327 return UseAlternateNextHandler(handler.Pass()); 329 return UseAlternateNextHandler(handler.Pass(), payload);
330 }
328 331
329 #if defined(ENABLE_PLUGINS) 332 #if defined(ENABLE_PLUGINS)
330 bool stale; 333 bool stale;
331 bool has_plugin = HasSupportingPlugin(&stale); 334 bool has_plugin = HasSupportingPlugin(&stale);
332 if (stale) { 335 if (stale) {
333 // Refresh the plugins asynchronously. 336 // Refresh the plugins asynchronously.
334 PluginServiceImpl::GetInstance()->GetPlugins( 337 PluginServiceImpl::GetInstance()->GetPlugins(
335 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, 338 base::Bind(&BufferedResourceHandler::OnPluginsLoaded,
336 weak_ptr_factory_.GetWeakPtr())); 339 weak_ptr_factory_.GetWeakPtr()));
337 request()->LogBlockedBy("BufferedResourceHandler"); 340 request()->LogBlockedBy("BufferedResourceHandler");
338 *defer = true; 341 *defer = true;
339 return true; 342 return true;
340 } 343 }
341 if (has_plugin) 344 if (has_plugin)
342 return true; 345 return true;
343 #endif 346 #endif
344 } 347 }
345 348
346 // Install download handler 349 // Install download handler
347 info->set_is_download(true); 350 info->set_is_download(true);
348 scoped_ptr<ResourceHandler> handler( 351 scoped_ptr<ResourceHandler> handler(
349 host_->CreateResourceHandlerForDownload( 352 host_->CreateResourceHandlerForDownload(
350 request(), 353 request(),
351 true, // is_content_initiated 354 true, // is_content_initiated
352 must_download, 355 must_download,
353 content::DownloadItem::kInvalidId, 356 content::DownloadItem::kInvalidId,
354 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()), 357 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()),
355 DownloadUrlParameters::OnStartedCallback())); 358 DownloadUrlParameters::OnStartedCallback()));
356 return UseAlternateNextHandler(handler.Pass()); 359 return UseAlternateNextHandler(handler.Pass(), std::string());
357 } 360 }
358 361
359 bool BufferedResourceHandler::UseAlternateNextHandler( 362 bool BufferedResourceHandler::UseAlternateNextHandler(
360 scoped_ptr<ResourceHandler> new_handler) { 363 scoped_ptr<ResourceHandler> new_handler,
361 if (response_->head.headers.get() && // Can be NULL if FTP. 364 const std::string& payload_for_old_handler) {
362 response_->head.headers->response_code() / 100 != 2) { 365 if (payload_for_old_handler.empty()) {
mmenke 2014/05/29 16:10:29 Suggest a short comment about this check here.
Zachary Kuznia 2014/05/29 20:42:40 After further consideration, I decided that this e
363 // The response code indicates that this is an error page, but we don't 366 if (response_->head.headers.get() && // Can be NULL if FTP.
364 // know how to display the content. We follow Firefox here and show our 367 response_->head.headers->response_code() / 100 != 2) {
365 // own error page instead of triggering a download. 368 // The response code indicates that this is an error page, but we don't
366 // TODO(abarth): We should abstract the response_code test, but this kind 369 // know how to display the content. We follow Firefox here and show our
367 // of check is scattered throughout our codebase. 370 // own error page instead of triggering a download.
368 request()->CancelWithError(net::ERR_INVALID_RESPONSE); 371 // TODO(abarth): We should abstract the response_code test, but this kind
369 return false; 372 // of check is scattered throughout our codebase.
373 request()->CancelWithError(net::ERR_INVALID_RESPONSE);
374 return false;
375 }
370 } 376 }
371 377
372 int request_id = GetRequestID(); 378 int request_id = GetRequestID();
373 379
374 // Inform the original ResourceHandler that this will be handled entirely by 380 // Inform the original ResourceHandler that this will be handled entirely by
375 // the new ResourceHandler. 381 // the new ResourceHandler.
376 // TODO(darin): We should probably check the return values of these. 382 // TODO(darin): We should probably check the return values of these.
377 bool defer_ignored = false; 383 bool defer_ignored = false;
378 next_handler_->OnResponseStarted(request_id, response_.get(), &defer_ignored); 384 next_handler_->OnResponseStarted(request_id, response_.get(), &defer_ignored);
379 // Although deferring OnResponseStarted is legal, the only downstream handler 385 // Although deferring OnResponseStarted is legal, the only downstream handler
380 // which does so is CrossSiteResourceHandler. Cross-site transitions should 386 // which does so is CrossSiteResourceHandler. Cross-site transitions should
381 // not trigger when switching handlers. 387 // not trigger when switching handlers.
382 DCHECK(!defer_ignored); 388 DCHECK(!defer_ignored);
383 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, 389 if (payload_for_old_handler.empty()) {
384 net::ERR_ABORTED); 390 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
385 next_handler_->OnResponseCompleted(request_id, status, std::string(), 391 net::ERR_ABORTED);
386 &defer_ignored); 392 next_handler_->OnResponseCompleted(request_id, status, std::string(),
387 DCHECK(!defer_ignored); 393 &defer_ignored);
394 DCHECK(!defer_ignored);
395 } else {
396 scoped_refptr<net::IOBuffer> buf;
397 int size = 0;
398
399 next_handler_->OnWillRead(request_id, &buf, &size,
400 payload_for_old_handler.length());
401 CHECK(size >= (int)payload_for_old_handler.length());
mmenke 2014/05/29 16:10:29 nit: CHECK_GE
mmenke 2014/05/29 16:10:29 C-style casts are forbidden. use static_cast.
Zachary Kuznia 2014/05/29 20:42:40 Done.
402
403 memcpy(buf->data(), payload_for_old_handler.c_str(),
404 payload_for_old_handler.length());
405
406 defer_ignored = false;
mmenke 2014/05/29 16:10:29 This isn't done on the above "next_handler_->OnRes
Zachary Kuznia 2014/05/29 20:42:40 Done.
407 next_handler_->OnReadCompleted(request_id, payload_for_old_handler.length(),
408 &defer_ignored);
409 DCHECK(!defer_ignored);
410
411 defer_ignored = false;
412 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
413 next_handler_->OnResponseCompleted(request_id, status, std::string(),
414 &defer_ignored);
415 DCHECK(!defer_ignored);
416 }
388 417
389 // This is handled entirely within the new ResourceHandler, so just reset the 418 // This is handled entirely within the new ResourceHandler, so just reset the
390 // original ResourceHandler. 419 // original ResourceHandler.
391 next_handler_ = new_handler.Pass(); 420 next_handler_ = new_handler.Pass();
392 next_handler_->SetController(this); 421 next_handler_->SetController(this);
393 422
394 return CopyReadBufferToNextHandler(request_id); 423 return CopyReadBufferToNextHandler(request_id);
395 } 424 }
396 425
397 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) { 426 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 request()->LogUnblocked(); 506 request()->LogUnblocked();
478 bool defer = false; 507 bool defer = false;
479 if (!ProcessResponse(&defer)) { 508 if (!ProcessResponse(&defer)) {
480 controller()->Cancel(); 509 controller()->Cancel();
481 } else if (!defer) { 510 } else if (!defer) {
482 controller()->Resume(); 511 controller()->Resume();
483 } 512 }
484 } 513 }
485 514
486 } // namespace content 515 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698