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

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 1417323006: OOPIFs: Deduplicating MHTML parts across frames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mhtml-serialization-per-frame
Patch Set: Addressed CR feedback from rdsmith@. Created 4 years, 11 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/auto_reset.h" 11 #include "base/auto_reset.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/alias.h" 13 #include "base/debug/alias.h"
14 #include "base/debug/asan_invalid_access.h" 14 #include "base/debug/asan_invalid_access.h"
15 #include "base/debug/dump_without_crashing.h" 15 #include "base/debug/dump_without_crashing.h"
16 #include "base/files/file.h" 16 #include "base/files/file.h"
17 #include "base/i18n/char_iterator.h" 17 #include "base/i18n/char_iterator.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/macros.h"
19 #include "base/memory/shared_memory.h" 20 #include "base/memory/shared_memory.h"
20 #include "base/memory/weak_ptr.h" 21 #include "base/memory/weak_ptr.h"
21 #include "base/metrics/histogram.h" 22 #include "base/metrics/histogram.h"
22 #include "base/process/process.h" 23 #include "base/process/process.h"
24 #include "base/stl_util.h"
23 #include "base/strings/string16.h" 25 #include "base/strings/string16.h"
24 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
25 #include "base/thread_task_runner_handle.h" 27 #include "base/thread_task_runner_handle.h"
26 #include "base/time/time.h" 28 #include "base/time/time.h"
27 #include "cc/base/switches.h" 29 #include "cc/base/switches.h"
28 #include "components/scheduler/renderer/renderer_scheduler.h" 30 #include "components/scheduler/renderer/renderer_scheduler.h"
29 #include "content/child/appcache/appcache_dispatcher.h" 31 #include "content/child/appcache/appcache_dispatcher.h"
30 #include "content/child/permissions/permission_dispatcher.h" 32 #include "content/child/permissions/permission_dispatcher.h"
31 #include "content/child/plugin_messages.h" 33 #include "content/child/plugin_messages.h"
32 #include "content/child/quota_dispatcher.h" 34 #include "content/child/quota_dispatcher.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 #include "content/renderer/savable_resources.h" 120 #include "content/renderer/savable_resources.h"
119 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h" 121 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h"
120 #include "content/renderer/shared_worker_repository.h" 122 #include "content/renderer/shared_worker_repository.h"
121 #include "content/renderer/skia_benchmarking_extension.h" 123 #include "content/renderer/skia_benchmarking_extension.h"
122 #include "content/renderer/stats_collection_controller.h" 124 #include "content/renderer/stats_collection_controller.h"
123 #include "content/renderer/usb/web_usb_client_impl.h" 125 #include "content/renderer/usb/web_usb_client_impl.h"
124 #include "content/renderer/wake_lock/wake_lock_dispatcher.h" 126 #include "content/renderer/wake_lock/wake_lock_dispatcher.h"
125 #include "content/renderer/web_frame_utils.h" 127 #include "content/renderer/web_frame_utils.h"
126 #include "content/renderer/web_ui_extension.h" 128 #include "content/renderer/web_ui_extension.h"
127 #include "content/renderer/websharedworker_proxy.h" 129 #include "content/renderer/websharedworker_proxy.h"
130 #include "crypto/sha2.h"
128 #include "gin/modules/module_registry.h" 131 #include "gin/modules/module_registry.h"
129 #include "media/audio/audio_output_device.h" 132 #include "media/audio/audio_output_device.h"
130 #include "media/base/audio_renderer_mixer_input.h" 133 #include "media/base/audio_renderer_mixer_input.h"
131 #include "media/base/media_log.h" 134 #include "media/base/media_log.h"
132 #include "media/base/media_switches.h" 135 #include "media/base/media_switches.h"
133 #include "media/blink/url_index.h" 136 #include "media/blink/url_index.h"
134 #include "media/blink/webencryptedmediaclient_impl.h" 137 #include "media/blink/webencryptedmediaclient_impl.h"
135 #include "media/blink/webmediaplayer_impl.h" 138 #include "media/blink/webmediaplayer_impl.h"
136 #include "media/renderers/gpu_video_accelerator_factories.h" 139 #include "media/renderers/gpu_video_accelerator_factories.h"
137 #include "mojo/common/url_type_converters.h" 140 #include "mojo/common/url_type_converters.h"
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 574
572 void OnGotContentHandlerID(uint32_t content_handler_id) {} 575 void OnGotContentHandlerID(uint32_t content_handler_id) {}
573 576
574 WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) { 577 WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
575 DCHECK(!path.IsAbsolute()); 578 DCHECK(!path.IsAbsolute());
576 return WebString::fromUTF8( 579 return WebString::fromUTF8(
577 std::string("./") + 580 std::string("./") +
578 path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe()); 581 path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
579 } 582 }
580 583
584 // Implementation of WebPageSerializer::MHTMLPartsGenerationDelegate that
585 // 1. Bases shouldSkipResource and getContentID responses on contents of
586 // FrameMsg_SerializeAsMHTML_Params.
587 // 2. Stores digests of urls of serialized resources (i.e. urls reported via
588 // shouldSkipResource) into |digests_of_uris_of_serialized_resources| passed
589 // to the constructor.
590 class MHTMLPartsGenerationDelegate
591 : public WebPageSerializer::MHTMLPartsGenerationDelegate {
592 public:
593 MHTMLPartsGenerationDelegate(
594 const FrameMsg_SerializeAsMHTML_Params& params,
595 std::set<std::string>* digests_of_uris_of_serialized_resources)
596 : params_(params),
597 digests_of_uris_of_serialized_resources_(
598 digests_of_uris_of_serialized_resources) {
599 DCHECK(digests_of_uris_of_serialized_resources_);
600 }
601
602 bool shouldSkipResource(const WebURL& url) override {
603 std::string digest =
604 crypto::SHA256HashString(params_.salt + GURL(url).spec());
605
606 // Skip if the |url| already covered by serialization of an *earlier* frame.
607 if (ContainsKey(params_.digests_of_uris_to_skip, digest))
608 return true;
609
610 // Let's record |url| as being serialized for the *current* frame.
611 auto pair = digests_of_uris_of_serialized_resources_->insert(digest);
612 bool insertion_took_place = pair.second;
nasko 2015/12/30 19:22:26 nit: I'd skip this local variable and DCHECK the p
Łukasz Anforowicz 2015/12/30 19:47:10 I don't know. I always have to look-up std lib's
613
614 // Blink should take care of deduping within a single (current) frame.
nasko 2015/12/30 19:22:26 nit: No need for "single (current)" part.
Łukasz Anforowicz 2015/12/30 19:47:10 Done.
615 DCHECK(insertion_took_place);
616
617 return false;
618 }
619
620 WebString getContentID(const WebFrame& frame) override {
621 int routing_id = GetRoutingIdForFrameOrProxy(const_cast<WebFrame*>(&frame));
622 auto it = params_.frame_routing_id_to_content_id.find(routing_id);
623 DCHECK(it != params_.frame_routing_id_to_content_id.end());
624 const std::string& content_id = it->second;
625 return WebString::fromUTF8(content_id);
626 }
627
628 private:
629 const FrameMsg_SerializeAsMHTML_Params& params_;
630 std::set<std::string>* digests_of_uris_of_serialized_resources_;
631
632 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate);
633 };
634
581 bool IsContentWithCertificateErrorsRelevantToUI( 635 bool IsContentWithCertificateErrorsRelevantToUI(
582 const blink::WebURL& url, 636 const blink::WebURL& url,
583 const blink::WebCString& security_info, 637 const blink::WebCString& security_info,
584 const blink::WebURL& main_resource_url, 638 const blink::WebURL& main_resource_url,
585 const blink::WebCString& main_resource_security_info) { 639 const blink::WebCString& main_resource_security_info) {
586 content::SSLStatus ssl_status; 640 content::SSLStatus ssl_status;
587 content::SSLStatus main_resource_ssl_status; 641 content::SSLStatus main_resource_ssl_status;
588 CHECK(DeserializeSecurityInfo(security_info, &ssl_status)); 642 CHECK(DeserializeSecurityInfo(security_info, &ssl_status));
589 CHECK(DeserializeSecurityInfo(main_resource_security_info, 643 CHECK(DeserializeSecurityInfo(main_resource_security_info,
590 &main_resource_ssl_status)); 644 &main_resource_ssl_status));
(...skipping 4171 matching lines...) Expand 10 before | Expand all | Expand 10 after
4762 WebURL(url), ConvertRelativePathToHtmlAttribute(local_path))); 4816 WebURL(url), ConvertRelativePathToHtmlAttribute(local_path)));
4763 } 4817 }
4764 4818
4765 // Serialize the frame (without recursing into subframes). 4819 // Serialize the frame (without recursing into subframes).
4766 WebPageSerializer::serialize(GetWebFrame(), 4820 WebPageSerializer::serialize(GetWebFrame(),
4767 this, // WebPageSerializerClient. 4821 this, // WebPageSerializerClient.
4768 weburl_to_local_path); 4822 weburl_to_local_path);
4769 } 4823 }
4770 4824
4771 void RenderFrameImpl::OnSerializeAsMHTML( 4825 void RenderFrameImpl::OnSerializeAsMHTML(
4772 int job_id, 4826 const FrameMsg_SerializeAsMHTML_Params& params) {
4773 IPC::PlatformFileForTransit file_for_transit,
4774 const std::string& std_mhtml_boundary,
4775 const std::map<int, std::string>& frame_routing_id_to_content_id,
4776 bool is_last_frame) {
4777 // Unpack IPC payload. 4827 // Unpack IPC payload.
4778 base::File file = IPC::PlatformFileForTransitToFile(file_for_transit); 4828 base::File file = IPC::PlatformFileForTransitToFile(params.destination_file);
4779 const WebString mhtml_boundary = WebString::fromUTF8(std_mhtml_boundary); 4829 const WebString mhtml_boundary =
4830 WebString::fromUTF8(params.mhtml_boundary_marker);
4780 DCHECK(!mhtml_boundary.isEmpty()); 4831 DCHECK(!mhtml_boundary.isEmpty());
4781 std::vector<std::pair<WebFrame*, WebString>> web_frame_to_content_id;
4782 for (const auto& it : frame_routing_id_to_content_id) {
4783 const std::string& content_id = it.second;
4784 WebFrame* web_frame = GetWebFrameFromRoutingIdForFrameOrProxy(it.first);
4785 if (!web_frame)
4786 continue;
4787
4788 web_frame_to_content_id.push_back(
4789 std::make_pair(web_frame, WebString::fromUTF8(content_id)));
4790 }
4791 4832
4792 WebData data; 4833 WebData data;
4793 bool success = true; 4834 bool success = true;
4835 std::set<std::string> digests_of_uris_of_serialized_resources;
4836 MHTMLPartsGenerationDelegate delegate(
4837 params, &digests_of_uris_of_serialized_resources);
4794 4838
4795 // Generate MHTML header if needed. 4839 // Generate MHTML header if needed.
4796 if (IsMainFrame()) { 4840 if (IsMainFrame()) {
4797 data = 4841 data =
4798 WebPageSerializer::generateMHTMLHeader(mhtml_boundary, GetWebFrame()); 4842 WebPageSerializer::generateMHTMLHeader(mhtml_boundary, GetWebFrame());
4799 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4843 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4800 success = false; 4844 success = false;
4801 } 4845 }
4802 } 4846 }
4803 4847
4804 // Generate MHTML parts. 4848 // Generate MHTML parts.
4805 if (success) { 4849 if (success) {
4806 data = WebPageSerializer::generateMHTMLParts( 4850 data = WebPageSerializer::generateMHTMLParts(mhtml_boundary, GetWebFrame(),
4807 mhtml_boundary, GetWebFrame(), false, web_frame_to_content_id); 4851 false, &delegate);
4808 // TODO(jcivelli): write the chunks in deferred tasks to give a chance to 4852 // TODO(jcivelli): write the chunks in deferred tasks to give a chance to
4809 // the message loop to process other events. 4853 // the message loop to process other events.
4810 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4854 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4811 success = false; 4855 success = false;
4812 } 4856 }
4813 } 4857 }
4814 4858
4815 // Generate MHTML footer if needed. 4859 // Generate MHTML footer if needed.
4816 if (success && is_last_frame) { 4860 if (success && params.is_last_frame) {
4817 data = WebPageSerializer::generateMHTMLFooter(mhtml_boundary); 4861 data = WebPageSerializer::generateMHTMLFooter(mhtml_boundary);
4818 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4862 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4819 success = false; 4863 success = false;
4820 } 4864 }
4821 } 4865 }
4822 4866
4823 // Cleanup and notify the browser process about completion. 4867 // Cleanup and notify the browser process about completion.
4824 file.Close(); // Need to flush file contents before sending IPC response. 4868 file.Close(); // Need to flush file contents before sending IPC response.
4825 Send(new FrameHostMsg_SerializeAsMHTMLResponse(routing_id_, job_id, success)); 4869 Send(new FrameHostMsg_SerializeAsMHTMLResponse(
4870 routing_id_, params.job_id, success,
4871 digests_of_uris_of_serialized_resources));
4826 } 4872 }
4827 4873
4828 void RenderFrameImpl::OpenURL(const GURL& url, 4874 void RenderFrameImpl::OpenURL(const GURL& url,
4829 const Referrer& referrer, 4875 const Referrer& referrer,
4830 WebNavigationPolicy policy, 4876 WebNavigationPolicy policy,
4831 bool should_replace_current_entry, 4877 bool should_replace_current_entry,
4832 bool is_history_navigation_in_new_child) { 4878 bool is_history_navigation_in_new_child) {
4833 FrameHostMsg_OpenURL_Params params; 4879 FrameHostMsg_OpenURL_Params params;
4834 params.url = url; 4880 params.url = url;
4835 params.referrer = referrer; 4881 params.referrer = referrer;
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after
5642 media::ConvertToSwitchOutputDeviceCB(web_callbacks); 5688 media::ConvertToSwitchOutputDeviceCB(web_callbacks);
5643 scoped_refptr<media::AudioOutputDevice> device = 5689 scoped_refptr<media::AudioOutputDevice> device =
5644 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(), 5690 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(),
5645 security_origin); 5691 security_origin);
5646 media::OutputDeviceStatus status = device->GetDeviceStatus(); 5692 media::OutputDeviceStatus status = device->GetDeviceStatus();
5647 device->Stop(); 5693 device->Stop();
5648 callback.Run(status); 5694 callback.Run(status);
5649 } 5695 }
5650 5696
5651 } // namespace content 5697 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698