| Index: content/renderer/render_frame_impl.cc
|
| diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
| index 180be854bd6e66044de5333916c94dbf56058b6b..a6d24f27a6685d8352e9541933da346b2bf6b11f 100644
|
| --- a/content/renderer/render_frame_impl.cc
|
| +++ b/content/renderer/render_frame_impl.cc
|
| @@ -17,10 +17,12 @@
|
| #include "base/files/file.h"
|
| #include "base/i18n/char_iterator.h"
|
| #include "base/logging.h"
|
| +#include "base/macros.h"
|
| #include "base/memory/shared_memory.h"
|
| #include "base/memory/weak_ptr.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/process/process.h"
|
| +#include "base/stl_util.h"
|
| #include "base/strings/string16.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/thread_task_runner_handle.h"
|
| @@ -127,6 +129,7 @@
|
| #include "content/renderer/web_frame_utils.h"
|
| #include "content/renderer/web_ui_extension.h"
|
| #include "content/renderer/websharedworker_proxy.h"
|
| +#include "crypto/sha2.h"
|
| #include "gin/modules/module_registry.h"
|
| #include "media/audio/audio_output_device.h"
|
| #include "media/base/audio_renderer_mixer_input.h"
|
| @@ -580,6 +583,55 @@ WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
|
| path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
|
| }
|
|
|
| +// Implementation of WebPageSerializer::MHTMLPartsGenerationDelegate that
|
| +// 1. Bases shouldSkipResource and getContentID responses on contents of
|
| +// FrameMsg_SerializeAsMHTML_Params.
|
| +// 2. Stores digests of urls of serialized resources (i.e. urls reported via
|
| +// shouldSkipResource) into |digests_of_uris_of_serialized_resources| passed
|
| +// to the constructor.
|
| +class MHTMLPartsGenerationDelegate
|
| + : public WebPageSerializer::MHTMLPartsGenerationDelegate {
|
| + public:
|
| + MHTMLPartsGenerationDelegate(
|
| + const FrameMsg_SerializeAsMHTML_Params& params,
|
| + std::set<std::string>* digests_of_uris_of_serialized_resources)
|
| + : params_(params),
|
| + digests_of_uris_of_serialized_resources_(
|
| + digests_of_uris_of_serialized_resources) {
|
| + DCHECK(digests_of_uris_of_serialized_resources_);
|
| + }
|
| +
|
| + bool shouldSkipResource(const WebURL& url) override {
|
| + std::string digest =
|
| + crypto::SHA256HashString(params_.salt + GURL(url).spec());
|
| +
|
| + // Skip if the |url| already covered by serialization of an *earlier* frame.
|
| + if (ContainsKey(params_.digests_of_uris_to_skip, digest))
|
| + return true;
|
| +
|
| + // Let's record |url| as being serialized for the *current* frame.
|
| + auto pair = digests_of_uris_of_serialized_resources_->insert(digest);
|
| + bool insertion_took_place = pair.second;
|
| + DCHECK(insertion_took_place); // Blink should dedupe within a frame.
|
| +
|
| + return false;
|
| + }
|
| +
|
| + WebString getContentID(const WebFrame& frame) override {
|
| + int routing_id = GetRoutingIdForFrameOrProxy(const_cast<WebFrame*>(&frame));
|
| + auto it = params_.frame_routing_id_to_content_id.find(routing_id);
|
| + DCHECK(it != params_.frame_routing_id_to_content_id.end());
|
| + const std::string& content_id = it->second;
|
| + return WebString::fromUTF8(content_id);
|
| + }
|
| +
|
| + private:
|
| + const FrameMsg_SerializeAsMHTML_Params& params_;
|
| + std::set<std::string>* digests_of_uris_of_serialized_resources_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate);
|
| +};
|
| +
|
| bool IsContentWithCertificateErrorsRelevantToUI(
|
| const blink::WebURL& url,
|
| const blink::WebCString& security_info,
|
| @@ -4766,28 +4818,18 @@ void RenderFrameImpl::OnGetSerializedHtmlWithLocalLinks(
|
| }
|
|
|
| void RenderFrameImpl::OnSerializeAsMHTML(
|
| - int job_id,
|
| - IPC::PlatformFileForTransit file_for_transit,
|
| - const std::string& std_mhtml_boundary,
|
| - const std::map<int, std::string>& frame_routing_id_to_content_id,
|
| - bool is_last_frame) {
|
| + const FrameMsg_SerializeAsMHTML_Params& params) {
|
| // Unpack IPC payload.
|
| - base::File file = IPC::PlatformFileForTransitToFile(file_for_transit);
|
| - const WebString mhtml_boundary = WebString::fromUTF8(std_mhtml_boundary);
|
| + base::File file = IPC::PlatformFileForTransitToFile(params.destination_file);
|
| + const WebString mhtml_boundary =
|
| + WebString::fromUTF8(params.mhtml_boundary_marker);
|
| DCHECK(!mhtml_boundary.isEmpty());
|
| - std::vector<std::pair<WebFrame*, WebString>> web_frame_to_content_id;
|
| - for (const auto& it : frame_routing_id_to_content_id) {
|
| - const std::string& content_id = it.second;
|
| - WebFrame* web_frame = GetWebFrameFromRoutingIdForFrameOrProxy(it.first);
|
| - if (!web_frame)
|
| - continue;
|
| -
|
| - web_frame_to_content_id.push_back(
|
| - std::make_pair(web_frame, WebString::fromUTF8(content_id)));
|
| - }
|
|
|
| WebData data;
|
| bool success = true;
|
| + std::set<std::string> digests_of_uris_of_serialized_resources;
|
| + MHTMLPartsGenerationDelegate delegate(
|
| + params, &digests_of_uris_of_serialized_resources);
|
|
|
| // Generate MHTML header if needed.
|
| if (IsMainFrame()) {
|
| @@ -4800,8 +4842,8 @@ void RenderFrameImpl::OnSerializeAsMHTML(
|
|
|
| // Generate MHTML parts.
|
| if (success) {
|
| - data = WebPageSerializer::generateMHTMLParts(
|
| - mhtml_boundary, GetWebFrame(), false, web_frame_to_content_id);
|
| + data = WebPageSerializer::generateMHTMLParts(mhtml_boundary, GetWebFrame(),
|
| + false, &delegate);
|
| // TODO(jcivelli): write the chunks in deferred tasks to give a chance to
|
| // the message loop to process other events.
|
| if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
|
| @@ -4810,7 +4852,7 @@ void RenderFrameImpl::OnSerializeAsMHTML(
|
| }
|
|
|
| // Generate MHTML footer if needed.
|
| - if (success && is_last_frame) {
|
| + if (success && params.is_last_frame) {
|
| data = WebPageSerializer::generateMHTMLFooter(mhtml_boundary);
|
| if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
|
| success = false;
|
| @@ -4819,7 +4861,9 @@ void RenderFrameImpl::OnSerializeAsMHTML(
|
|
|
| // Cleanup and notify the browser process about completion.
|
| file.Close(); // Need to flush file contents before sending IPC response.
|
| - Send(new FrameHostMsg_SerializeAsMHTMLResponse(routing_id_, job_id, success));
|
| + Send(new FrameHostMsg_SerializeAsMHTMLResponse(
|
| + routing_id_, params.job_id, success,
|
| + digests_of_uris_of_serialized_resources));
|
| }
|
|
|
| void RenderFrameImpl::OpenURL(const GURL& url,
|
|
|