#include "content/browser/download/mhtml_generation_manager.h"
#include <tuple>
#include <utility>
#include "base/containers/queue.h"
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/types/optional_util.h"
#include "base/uuid.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/bad_message.h"
#include "content/browser/download/mhtml_extra_parts_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/download/mhtml_file_writer.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/mhtml_extra_parts.h"
#include "content/public/browser/mhtml_generation_result.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/mhtml_generation_params.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "net/base/mime_util.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/win/security_util.h"
#include "base/win/sid.h"
#endif
namespace {
MHTMLWriteCompleteCallback;
const char kContentLocation[] = …;
const char kContentType[] = …;
int kInvalidFileSize = …;
#if BUILDFLAG(IS_WIN)
bool DenyExecuteAccessToMHTMLFile(const base::FilePath& path) {
static constexpr wchar_t kEveryoneSid[] = L"WD";
auto sids = base::win::Sid::FromSddlStringVector({kEveryoneSid});
if (!sids) {
return false;
}
return base::win::DenyAccessToPath(path, *sids, FILE_EXECUTE,
0, false);
}
#endif
struct CloseFileResult { … };
base::File CreateMHTMLFile(const base::FilePath& file_path) { … }
}
namespace content {
class MHTMLGenerationManager::Job { … };
MHTMLGenerationManager::Job::Job(
WebContents* web_contents,
const MHTMLGenerationParams& params,
MHTMLGenerationResult::GenerateMHTMLCallback callback)
: … { … }
MHTMLGenerationManager::Job::~Job() { … }
void MHTMLGenerationManager::Job::initializeJob(WebContents* web_contents) { … }
mojom::SerializeAsMHTMLParamsPtr
MHTMLGenerationManager::Job::CreateMojoParams() { … }
mojom::MhtmlSaveStatus MHTMLGenerationManager::Job::SendToNextRenderFrame() { … }
void MHTMLGenerationManager::Job::BeginWatchingHandle(
MHTMLWriteCompleteCallback callback) { … }
void MHTMLGenerationManager::Job::WriteMHTMLToDisk(
MHTMLWriteCompleteCallback callback,
MojoResult result,
const mojo::HandleSignalsState& state) { … }
void MHTMLGenerationManager::Job::OnWriteComplete(
MHTMLWriteCompleteCallback callback,
mojom::MhtmlSaveStatus save_status) { … }
void MHTMLGenerationManager::Job::DoneWritingToDisk(
mojom::MhtmlSaveStatus save_status) { … }
void MHTMLGenerationManager::Job::OnConnectionError() { … }
void MHTMLGenerationManager::Job::OnFileAvailable(base::File browser_file) { … }
void MHTMLGenerationManager::Job::OnFinished(
const CloseFileResult& close_file_result) { … }
void MHTMLGenerationManager::Job::MarkAsFinished() { … }
void MHTMLGenerationManager::Job::CloseFile(
mojom::MhtmlSaveStatus save_status) { … }
void MHTMLGenerationManager::Job::SerializeAsMHTMLResponse(
mojom::MhtmlSaveStatus save_status,
const std::vector<std::string>& digests_of_uris_of_serialized_resources) { … }
void MHTMLGenerationManager::Job::RecordDigests(
const std::vector<std::string>& digests_of_uris_of_serialized_resources) { … }
void MHTMLGenerationManager::Job::MaybeSendToNextRenderFrame(
mojom::MhtmlSaveStatus save_status) { … }
bool MHTMLGenerationManager::Job::CurrentFrameDone() const { … }
void MHTMLGenerationManager::Job::Finalize(mojom::MhtmlSaveStatus save_status) { … }
void MHTMLGenerationManager::Job::StartNewJob(
WebContents* web_contents,
const MHTMLGenerationParams& params,
MHTMLGenerationResult::GenerateMHTMLCallback callback) { … }
bool MHTMLGenerationManager::Job::WriteToFileAndUpdateHash(
base::File* file,
crypto::SecureHash* secure_hash,
std::string to_write) { … }
CloseFileResult MHTMLGenerationManager::Job::FinalizeOnFileThread(
mojom::MhtmlSaveStatus save_status,
const std::string& boundary,
base::File file,
const std::vector<MHTMLExtraDataPart>& extra_data_parts,
std::unique_ptr<mojo::SimpleWatcher> watcher,
std::unique_ptr<crypto::SecureHash> secure_hash) { … }
std::string MHTMLGenerationManager::Job::CreateExtraDataParts(
const std::string& boundary,
const std::vector<MHTMLExtraDataPart>& extra_data_parts) { … }
std::string MHTMLGenerationManager::Job::CreateFooter(
const std::string& boundary) { … }
bool MHTMLGenerationManager::Job::CloseFileIfValid(base::File& file,
int64_t* file_size) { … }
MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() { … }
MHTMLGenerationManager::MHTMLGenerationManager() = default;
MHTMLGenerationManager::~MHTMLGenerationManager() = default;
void MHTMLGenerationManager::SaveMHTML(
WebContents* web_contents,
const MHTMLGenerationParams& params,
MHTMLGenerationResult::GenerateMHTMLCallback callback) { … }
}