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

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: Rebasing... 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 <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/auto_reset.h" 12 #include "base/auto_reset.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/debug/alias.h" 14 #include "base/debug/alias.h"
15 #include "base/debug/asan_invalid_access.h" 15 #include "base/debug/asan_invalid_access.h"
16 #include "base/debug/dump_without_crashing.h" 16 #include "base/debug/dump_without_crashing.h"
17 #include "base/files/file.h" 17 #include "base/files/file.h"
18 #include "base/i18n/char_iterator.h" 18 #include "base/i18n/char_iterator.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/macros.h"
20 #include "base/memory/shared_memory.h" 21 #include "base/memory/shared_memory.h"
21 #include "base/memory/weak_ptr.h" 22 #include "base/memory/weak_ptr.h"
22 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
23 #include "base/process/process.h" 24 #include "base/process/process.h"
25 #include "base/stl_util.h"
24 #include "base/strings/string16.h" 26 #include "base/strings/string16.h"
25 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
26 #include "base/thread_task_runner_handle.h" 28 #include "base/thread_task_runner_handle.h"
27 #include "base/time/time.h" 29 #include "base/time/time.h"
28 #include "build/build_config.h" 30 #include "build/build_config.h"
29 #include "cc/base/switches.h" 31 #include "cc/base/switches.h"
30 #include "components/scheduler/renderer/renderer_scheduler.h" 32 #include "components/scheduler/renderer/renderer_scheduler.h"
31 #include "content/child/appcache/appcache_dispatcher.h" 33 #include "content/child/appcache/appcache_dispatcher.h"
32 #include "content/child/permissions/permission_dispatcher.h" 34 #include "content/child/permissions/permission_dispatcher.h"
33 #include "content/child/plugin_messages.h" 35 #include "content/child/plugin_messages.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 #include "content/renderer/savable_resources.h" 122 #include "content/renderer/savable_resources.h"
121 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h" 123 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h"
122 #include "content/renderer/shared_worker_repository.h" 124 #include "content/renderer/shared_worker_repository.h"
123 #include "content/renderer/skia_benchmarking_extension.h" 125 #include "content/renderer/skia_benchmarking_extension.h"
124 #include "content/renderer/stats_collection_controller.h" 126 #include "content/renderer/stats_collection_controller.h"
125 #include "content/renderer/usb/web_usb_client_impl.h" 127 #include "content/renderer/usb/web_usb_client_impl.h"
126 #include "content/renderer/wake_lock/wake_lock_dispatcher.h" 128 #include "content/renderer/wake_lock/wake_lock_dispatcher.h"
127 #include "content/renderer/web_frame_utils.h" 129 #include "content/renderer/web_frame_utils.h"
128 #include "content/renderer/web_ui_extension.h" 130 #include "content/renderer/web_ui_extension.h"
129 #include "content/renderer/websharedworker_proxy.h" 131 #include "content/renderer/websharedworker_proxy.h"
132 #include "crypto/sha2.h"
130 #include "gin/modules/module_registry.h" 133 #include "gin/modules/module_registry.h"
131 #include "media/audio/audio_output_device.h" 134 #include "media/audio/audio_output_device.h"
132 #include "media/base/audio_renderer_mixer_input.h" 135 #include "media/base/audio_renderer_mixer_input.h"
133 #include "media/base/media_log.h" 136 #include "media/base/media_log.h"
134 #include "media/base/media_switches.h" 137 #include "media/base/media_switches.h"
135 #include "media/blink/url_index.h" 138 #include "media/blink/url_index.h"
136 #include "media/blink/webencryptedmediaclient_impl.h" 139 #include "media/blink/webencryptedmediaclient_impl.h"
137 #include "media/blink/webmediaplayer_impl.h" 140 #include "media/blink/webmediaplayer_impl.h"
138 #include "media/renderers/gpu_video_accelerator_factories.h" 141 #include "media/renderers/gpu_video_accelerator_factories.h"
139 #include "mojo/common/url_type_converters.h" 142 #include "mojo/common/url_type_converters.h"
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 576
574 void OnGotContentHandlerID(uint32_t content_handler_id) {} 577 void OnGotContentHandlerID(uint32_t content_handler_id) {}
575 578
576 WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) { 579 WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
577 DCHECK(!path.IsAbsolute()); 580 DCHECK(!path.IsAbsolute());
578 return WebString::fromUTF8( 581 return WebString::fromUTF8(
579 std::string("./") + 582 std::string("./") +
580 path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe()); 583 path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
581 } 584 }
582 585
586 // Implementation of WebPageSerializer::MHTMLPartsGenerationDelegate that
587 // 1. Bases shouldSkipResource and getContentID responses on contents of
588 // FrameMsg_SerializeAsMHTML_Params.
589 // 2. Stores digests of urls of serialized resources (i.e. urls reported via
590 // shouldSkipResource) into |digests_of_uris_of_serialized_resources| passed
591 // to the constructor.
592 class MHTMLPartsGenerationDelegate
593 : public WebPageSerializer::MHTMLPartsGenerationDelegate {
594 public:
595 MHTMLPartsGenerationDelegate(
596 const FrameMsg_SerializeAsMHTML_Params& params,
597 std::set<std::string>* digests_of_uris_of_serialized_resources)
598 : params_(params),
599 digests_of_uris_of_serialized_resources_(
600 digests_of_uris_of_serialized_resources) {
601 DCHECK(digests_of_uris_of_serialized_resources_);
602 }
603
604 bool shouldSkipResource(const WebURL& url) override {
605 std::string digest =
606 crypto::SHA256HashString(params_.salt + GURL(url).spec());
607
608 // Skip if the |url| already covered by serialization of an *earlier* frame.
609 if (ContainsKey(params_.digests_of_uris_to_skip, digest))
610 return true;
611
612 // Let's record |url| as being serialized for the *current* frame.
613 auto pair = digests_of_uris_of_serialized_resources_->insert(digest);
614 bool insertion_took_place = pair.second;
615 DCHECK(insertion_took_place); // Blink should dedupe within a frame.
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
583 bool IsContentWithCertificateErrorsRelevantToUI( 635 bool IsContentWithCertificateErrorsRelevantToUI(
584 const blink::WebURL& url, 636 const blink::WebURL& url,
585 const blink::WebCString& security_info, 637 const blink::WebCString& security_info,
586 const blink::WebURL& main_resource_url, 638 const blink::WebURL& main_resource_url,
587 const blink::WebCString& main_resource_security_info) { 639 const blink::WebCString& main_resource_security_info) {
588 content::SSLStatus ssl_status; 640 content::SSLStatus ssl_status;
589 content::SSLStatus main_resource_ssl_status; 641 content::SSLStatus main_resource_ssl_status;
590 CHECK(DeserializeSecurityInfo(security_info, &ssl_status)); 642 CHECK(DeserializeSecurityInfo(security_info, &ssl_status));
591 CHECK(DeserializeSecurityInfo(main_resource_security_info, 643 CHECK(DeserializeSecurityInfo(main_resource_security_info,
592 &main_resource_ssl_status)); 644 &main_resource_ssl_status));
(...skipping 4166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4759 WebURL(url), ConvertRelativePathToHtmlAttribute(local_path))); 4811 WebURL(url), ConvertRelativePathToHtmlAttribute(local_path)));
4760 } 4812 }
4761 4813
4762 // Serialize the frame (without recursing into subframes). 4814 // Serialize the frame (without recursing into subframes).
4763 WebPageSerializer::serialize(GetWebFrame(), 4815 WebPageSerializer::serialize(GetWebFrame(),
4764 this, // WebPageSerializerClient. 4816 this, // WebPageSerializerClient.
4765 weburl_to_local_path); 4817 weburl_to_local_path);
4766 } 4818 }
4767 4819
4768 void RenderFrameImpl::OnSerializeAsMHTML( 4820 void RenderFrameImpl::OnSerializeAsMHTML(
4769 int job_id, 4821 const FrameMsg_SerializeAsMHTML_Params& params) {
4770 IPC::PlatformFileForTransit file_for_transit,
4771 const std::string& std_mhtml_boundary,
4772 const std::map<int, std::string>& frame_routing_id_to_content_id,
4773 bool is_last_frame) {
4774 // Unpack IPC payload. 4822 // Unpack IPC payload.
4775 base::File file = IPC::PlatformFileForTransitToFile(file_for_transit); 4823 base::File file = IPC::PlatformFileForTransitToFile(params.destination_file);
4776 const WebString mhtml_boundary = WebString::fromUTF8(std_mhtml_boundary); 4824 const WebString mhtml_boundary =
4825 WebString::fromUTF8(params.mhtml_boundary_marker);
4777 DCHECK(!mhtml_boundary.isEmpty()); 4826 DCHECK(!mhtml_boundary.isEmpty());
4778 std::vector<std::pair<WebFrame*, WebString>> web_frame_to_content_id;
4779 for (const auto& it : frame_routing_id_to_content_id) {
4780 const std::string& content_id = it.second;
4781 WebFrame* web_frame = GetWebFrameFromRoutingIdForFrameOrProxy(it.first);
4782 if (!web_frame)
4783 continue;
4784
4785 web_frame_to_content_id.push_back(
4786 std::make_pair(web_frame, WebString::fromUTF8(content_id)));
4787 }
4788 4827
4789 WebData data; 4828 WebData data;
4790 bool success = true; 4829 bool success = true;
4830 std::set<std::string> digests_of_uris_of_serialized_resources;
4831 MHTMLPartsGenerationDelegate delegate(
4832 params, &digests_of_uris_of_serialized_resources);
4791 4833
4792 // Generate MHTML header if needed. 4834 // Generate MHTML header if needed.
4793 if (IsMainFrame()) { 4835 if (IsMainFrame()) {
4794 data = 4836 data =
4795 WebPageSerializer::generateMHTMLHeader(mhtml_boundary, GetWebFrame()); 4837 WebPageSerializer::generateMHTMLHeader(mhtml_boundary, GetWebFrame());
4796 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4838 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4797 success = false; 4839 success = false;
4798 } 4840 }
4799 } 4841 }
4800 4842
4801 // Generate MHTML parts. 4843 // Generate MHTML parts.
4802 if (success) { 4844 if (success) {
4803 data = WebPageSerializer::generateMHTMLParts( 4845 data = WebPageSerializer::generateMHTMLParts(mhtml_boundary, GetWebFrame(),
4804 mhtml_boundary, GetWebFrame(), false, web_frame_to_content_id); 4846 false, &delegate);
4805 // TODO(jcivelli): write the chunks in deferred tasks to give a chance to 4847 // TODO(jcivelli): write the chunks in deferred tasks to give a chance to
4806 // the message loop to process other events. 4848 // the message loop to process other events.
4807 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4849 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4808 success = false; 4850 success = false;
4809 } 4851 }
4810 } 4852 }
4811 4853
4812 // Generate MHTML footer if needed. 4854 // Generate MHTML footer if needed.
4813 if (success && is_last_frame) { 4855 if (success && params.is_last_frame) {
4814 data = WebPageSerializer::generateMHTMLFooter(mhtml_boundary); 4856 data = WebPageSerializer::generateMHTMLFooter(mhtml_boundary);
4815 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) { 4857 if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
4816 success = false; 4858 success = false;
4817 } 4859 }
4818 } 4860 }
4819 4861
4820 // Cleanup and notify the browser process about completion. 4862 // Cleanup and notify the browser process about completion.
4821 file.Close(); // Need to flush file contents before sending IPC response. 4863 file.Close(); // Need to flush file contents before sending IPC response.
4822 Send(new FrameHostMsg_SerializeAsMHTMLResponse(routing_id_, job_id, success)); 4864 Send(new FrameHostMsg_SerializeAsMHTMLResponse(
4865 routing_id_, params.job_id, success,
4866 digests_of_uris_of_serialized_resources));
4823 } 4867 }
4824 4868
4825 void RenderFrameImpl::OpenURL(const GURL& url, 4869 void RenderFrameImpl::OpenURL(const GURL& url,
4826 const Referrer& referrer, 4870 const Referrer& referrer,
4827 WebNavigationPolicy policy, 4871 WebNavigationPolicy policy,
4828 bool should_replace_current_entry, 4872 bool should_replace_current_entry,
4829 bool is_history_navigation_in_new_child) { 4873 bool is_history_navigation_in_new_child) {
4830 FrameHostMsg_OpenURL_Params params; 4874 FrameHostMsg_OpenURL_Params params;
4831 params.url = url; 4875 params.url = url;
4832 params.referrer = referrer; 4876 params.referrer = referrer;
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
5640 media::ConvertToSwitchOutputDeviceCB(web_callbacks); 5684 media::ConvertToSwitchOutputDeviceCB(web_callbacks);
5641 scoped_refptr<media::AudioOutputDevice> device = 5685 scoped_refptr<media::AudioOutputDevice> device =
5642 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(), 5686 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(),
5643 security_origin); 5687 security_origin);
5644 media::OutputDeviceStatus status = device->GetDeviceStatus(); 5688 media::OutputDeviceStatus status = device->GetDeviceStatus();
5645 device->Stop(); 5689 device->Stop();
5646 callback.Run(status); 5690 callback.Run(status);
5647 } 5691 }
5648 5692
5649 } // namespace content 5693 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | third_party/WebKit/Source/core/page/PageSerializer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698