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

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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 DCHECK(!response_->head.mime_type.empty()); 299 DCHECK(!response_->head.mime_type.empty());
299 300
300 ResourceRequestInfoImpl* info = GetRequestInfo(); 301 ResourceRequestInfoImpl* info = GetRequestInfo();
301 const std::string& mime_type = response_->head.mime_type; 302 const std::string& mime_type = response_->head.mime_type;
302 303
303 if (net::IsSupportedCertificateMimeType(mime_type)) { 304 if (net::IsSupportedCertificateMimeType(mime_type)) {
304 // Install certificate file. 305 // Install certificate file.
305 info->set_is_download(true); 306 info->set_is_download(true);
306 scoped_ptr<ResourceHandler> handler( 307 scoped_ptr<ResourceHandler> handler(
307 new CertificateResourceHandler(request())); 308 new CertificateResourceHandler(request()));
308 return UseAlternateNextHandler(handler.Pass()); 309 return UseAlternateNextHandler(handler.Pass(), std::string());
309 } 310 }
310 311
311 if (!info->allow_download()) 312 if (!info->allow_download())
312 return true; 313 return true;
313 314
314 bool must_download = MustDownload(); 315 bool must_download = MustDownload();
315 if (!must_download) { 316 if (!must_download) {
316 if (net::IsSupportedMimeType(mime_type)) 317 if (net::IsSupportedMimeType(mime_type))
317 return true; 318 return true;
318 319
320 std::string payload;
319 scoped_ptr<ResourceHandler> handler( 321 scoped_ptr<ResourceHandler> handler(
320 host_->MaybeInterceptAsStream(request(), response_.get())); 322 host_->MaybeInterceptAsStream(request(), response_.get(), &payload));
321 if (handler) 323 if (handler) {
322 return UseAlternateNextHandler(handler.Pass()); 324 return UseAlternateNextHandler(handler.Pass(), payload);
325 }
323 326
324 #if defined(ENABLE_PLUGINS) 327 #if defined(ENABLE_PLUGINS)
325 bool stale; 328 bool stale;
326 bool has_plugin = HasSupportingPlugin(&stale); 329 bool has_plugin = HasSupportingPlugin(&stale);
327 if (stale) { 330 if (stale) {
328 // Refresh the plugins asynchronously. 331 // Refresh the plugins asynchronously.
329 PluginServiceImpl::GetInstance()->GetPlugins( 332 PluginServiceImpl::GetInstance()->GetPlugins(
330 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, 333 base::Bind(&BufferedResourceHandler::OnPluginsLoaded,
331 weak_ptr_factory_.GetWeakPtr())); 334 weak_ptr_factory_.GetWeakPtr()));
332 request()->LogBlockedBy("BufferedResourceHandler"); 335 request()->LogBlockedBy("BufferedResourceHandler");
333 *defer = true; 336 *defer = true;
334 return true; 337 return true;
335 } 338 }
336 if (has_plugin) 339 if (has_plugin)
337 return true; 340 return true;
338 #endif 341 #endif
339 } 342 }
340 343
341 // Install download handler 344 // Install download handler
342 info->set_is_download(true); 345 info->set_is_download(true);
343 scoped_ptr<ResourceHandler> handler( 346 scoped_ptr<ResourceHandler> handler(
344 host_->CreateResourceHandlerForDownload( 347 host_->CreateResourceHandlerForDownload(
345 request(), 348 request(),
346 true, // is_content_initiated 349 true, // is_content_initiated
347 must_download, 350 must_download,
348 content::DownloadItem::kInvalidId, 351 content::DownloadItem::kInvalidId,
349 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()), 352 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()),
350 DownloadUrlParameters::OnStartedCallback())); 353 DownloadUrlParameters::OnStartedCallback()));
351 return UseAlternateNextHandler(handler.Pass()); 354 return UseAlternateNextHandler(handler.Pass(), std::string());
352 } 355 }
353 356
354 bool BufferedResourceHandler::UseAlternateNextHandler( 357 bool BufferedResourceHandler::UseAlternateNextHandler(
355 scoped_ptr<ResourceHandler> new_handler) { 358 scoped_ptr<ResourceHandler> new_handler,
359 const std::string& payload_for_old_handler) {
356 if (response_->head.headers.get() && // Can be NULL if FTP. 360 if (response_->head.headers.get() && // Can be NULL if FTP.
357 response_->head.headers->response_code() / 100 != 2) { 361 response_->head.headers->response_code() / 100 != 2) {
358 // The response code indicates that this is an error page, but we don't 362 // The response code indicates that this is an error page, but we don't
359 // know how to display the content. We follow Firefox here and show our 363 // know how to display the content. We follow Firefox here and show our
360 // own error page instead of triggering a download. 364 // own error page instead of triggering a download.
361 // TODO(abarth): We should abstract the response_code test, but this kind 365 // TODO(abarth): We should abstract the response_code test, but this kind
362 // of check is scattered throughout our codebase. 366 // of check is scattered throughout our codebase.
363 request()->CancelWithError(net::ERR_INVALID_RESPONSE); 367 request()->CancelWithError(net::ERR_INVALID_RESPONSE);
364 return false; 368 return false;
365 } 369 }
366 370
367 // Inform the original ResourceHandler that this will be handled entirely by 371 // Inform the original ResourceHandler that this will be handled entirely by
368 // the new ResourceHandler. 372 // the new ResourceHandler.
369 // TODO(darin): We should probably check the return values of these. 373 // TODO(darin): We should probably check the return values of these.
370 bool defer_ignored = false; 374 bool defer_ignored = false;
371 next_handler_->OnResponseStarted(response_.get(), &defer_ignored); 375 next_handler_->OnResponseStarted(response_.get(), &defer_ignored);
372 // Although deferring OnResponseStarted is legal, the only downstream handler 376 // Although deferring OnResponseStarted is legal, the only downstream handler
373 // which does so is CrossSiteResourceHandler. Cross-site transitions should 377 // which does so is CrossSiteResourceHandler. Cross-site transitions should
374 // not trigger when switching handlers. 378 // not trigger when switching handlers.
375 DCHECK(!defer_ignored); 379 DCHECK(!defer_ignored);
376 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, 380 if (payload_for_old_handler.empty()) {
377 net::ERR_ABORTED); 381 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
378 next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored); 382 net::ERR_ABORTED);
379 DCHECK(!defer_ignored); 383 next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
384 DCHECK(!defer_ignored);
385 } else {
386 scoped_refptr<net::IOBuffer> buf;
387 int size = 0;
388
389 next_handler_->OnWillRead(&buf, &size, payload_for_old_handler.length());
390 CHECK_GE(size, static_cast<int>(payload_for_old_handler.length()));
391
392 memcpy(buf->data(), payload_for_old_handler.c_str(),
393 payload_for_old_handler.length());
394
395 next_handler_->OnReadCompleted(payload_for_old_handler.length(),
396 &defer_ignored);
397 DCHECK(!defer_ignored);
398
399 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
400 next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
401 DCHECK(!defer_ignored);
402 }
380 403
381 // This is handled entirely within the new ResourceHandler, so just reset the 404 // This is handled entirely within the new ResourceHandler, so just reset the
382 // original ResourceHandler. 405 // original ResourceHandler.
383 next_handler_ = new_handler.Pass(); 406 next_handler_ = new_handler.Pass();
384 next_handler_->SetController(this); 407 next_handler_->SetController(this);
385 408
386 return CopyReadBufferToNextHandler(); 409 return CopyReadBufferToNextHandler();
387 } 410 }
388 411
389 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) { 412 bool BufferedResourceHandler::ReplayReadCompleted(bool* defer) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 request()->LogUnblocked(); 491 request()->LogUnblocked();
469 bool defer = false; 492 bool defer = false;
470 if (!ProcessResponse(&defer)) { 493 if (!ProcessResponse(&defer)) {
471 controller()->Cancel(); 494 controller()->Cancel();
472 } else if (!defer) { 495 } else if (!defer) {
473 controller()->Resume(); 496 controller()->Resume();
474 } 497 }
475 } 498 }
476 499
477 } // namespace content 500 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698