chromium/content/browser/download/save_package.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/download/save_package.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "base/containers/contains.h"
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/i18n/file_util_icu.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/not_fatal_until.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "components/download/public/common/download_item_impl.h"
#include "components/download/public/common/download_save_item_data.h"
#include "components/download/public/common/download_stats.h"
#include "components/download/public/common/download_task_runner.h"
#include "components/download/public/common/download_ukm_helper.h"
#include "components/download/public/common/download_utils.h"
#include "components/filename_generation/filename_generation.h"
#include "components/url_formatter/url_formatter.h"
#include "content/browser/bad_message.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/save_file.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_item.h"
#include "content/browser/download/save_package_serialization_handler.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/page_impl.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/mhtml_generation_params.h"
#include "content/public/common/referrer_type_converters.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/filename_util.h"
#include "net/base/mime_util.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/network/public/cpp/request_mode.h"
#include "url/url_constants.h"

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

namespace content {
namespace {

// Generates unique ids for SavePackage::unique_id_ field.
SavePackageId GetNextSavePackageId() {}

// Default name which will be used when we can not get proper name from
// resource URL.
const char kDefaultSaveName[] =;

// Maximum number of file ordinal number. I think it's big enough for resolving
// name-conflict files which has same base file name.
const int32_t kMaxFileOrdinalNumber =;

// Maximum length for file path. Since Windows have MAX_PATH limitation for
// file path, we need to make sure length of file path of every saved file
// is less than MAX_PATH
#if BUILDFLAG(IS_WIN)
const uint32_t kMaxFilePathLength = MAX_PATH - 1;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
const uint32_t kMaxFilePathLength =;
#endif

// Maximum length for file ordinal number part. Since we only support the
// maximum 9999 for ordinal number, which means maximum file ordinal number part
// should be "(9998)", so the value is 6.
const uint32_t kMaxFileOrdinalNumberPartLength =;

// Strip current ordinal number, if any. Should only be used on pure
// file names, i.e. those stripped of their extensions.
// TODO(estade): improve this to not choke on alternate encodings.
base::FilePath::StringType StripOrdinalNumber(
    const base::FilePath::StringType& base_name) {}

// Check whether we can save page as complete-HTML for the contents which
// have specified a MIME type. Now only contents which have the MIME type
// "text/html" can be saved as complete-HTML.
bool CanSaveAsComplete(const std::string& contents_mime_type) {}

void CancelSavePackage(base::WeakPtr<SavePackage> save_package,
                       bool user_cancel) {}

const std::string GetMimeTypeForSaveType(SavePageType save_type) {}

WebContents* GetWebContents(Page* page) {}

const std::u16string& GetTitle(Page& page) {}

bool IsSavableFrame(RenderFrameHost* rfh) {}

}  // namespace

const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] =);

SavePackage::SavePackage(PageImpl& page)
    :{}

// Used for tests.
SavePackage::SavePackage(PageImpl& page,
                         SavePageType save_type,
                         const base::FilePath& file_full_path,
                         const base::FilePath& directory_full_path)
    :{}

SavePackage::~SavePackage() {}

void SavePackage::ClearPage() {}

// static
GURL SavePackage::GetUrlToBeSaved(RenderFrameHost* main_frame) {}

void SavePackage::Cancel(bool user_action, bool cancel_download_item) {}

// Init() can be called directly, or indirectly via GetSaveInfo(). In both
// cases, we need file_manager_ to be initialized, so we do this first.
void SavePackage::InternalInit() {}

bool SavePackage::Init(
    SavePackageDownloadCreatedCallback download_created_callback) {}

void SavePackage::InitWithDownloadItem(
    SavePackageDownloadCreatedCallback download_created_callback,
    download::DownloadItemImpl* item) {}

void SavePackage::OnMHTMLGenerated(int64_t size) {}

// On POSIX, the length of |base_name| + |file_name_ext| is further
// restricted by NAME_MAX. The maximum allowed path looks like:
// '/path/to/save_dir' + '/' + NAME_MAX.
uint32_t SavePackage::GetMaxPathLengthForDirectory(
    const base::FilePath& base_dir) {}

// static
bool SavePackage::TruncateBaseNameToFitPathConstraints(
    const base::FilePath& dir_path,
    const base::FilePath::StringType& file_name_ext,
    uint32_t max_file_path_len,
    base::FilePath::StringType* base_name) {}

// Generate name for saving resource.
bool SavePackage::GenerateFileName(const std::string& disposition,
                                   const GURL& url,
                                   bool need_html_ext,
                                   base::FilePath::StringType* generated_name) {}

// We have received a message from SaveFileManager about a new saving job. We
// find a SaveItem and store it in our in_progress list.
void SavePackage::StartSave(const SaveFileCreateInfo* info) {}

SaveItem* SavePackage::LookupInProgressSaveItem(SaveItemId save_item_id) {}

void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) {}

// Called for updating saving state.
bool SavePackage::UpdateSaveProgress(SaveItemId save_item_id,
                                     int64_t size,
                                     bool write_success) {}

// Stop all page saving jobs that are in progress and instruct the download
// sequence to delete all saved files.
void SavePackage::Stop(bool cancel_download_item) {}

void SavePackage::CheckFinish() {}

void SavePackage::CheckRenameAllowedForPaths(
    base::flat_map<base::FilePath, base::FilePath> tmp_paths_to_final_paths) {}

void SavePackage::RenameIfAllowed(bool allowed) {}

// Successfully finished all items of this SavePackage.
void SavePackage::Finish() {}

void SavePackage::SaveFinished(SaveItemId save_item_id,
                               int64_t size,
                               bool is_success) {}

void SavePackage::SaveCanceled(const SaveItem* save_item) {}

void SavePackage::SaveNextFile(bool process_all_remaining_items) {}

int SavePackage::PercentComplete() {}

int64_t SavePackage::CurrentSpeed() const {}

void SavePackage::DoSavingProcess() {}

// After finishing all SaveItems which need to get data from net.
// We collect all URLs which have local storage and send the
// map:(originalURL:currentLocalPath) to render process (backend).
// Then render process will serialize DOM and send data to us.
void SavePackage::GetSerializedHtmlWithLocalLinks() {}

void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
    FrameTreeNode* target_tree_node) {}

void SavePackage::OnDidReceiveSerializedHtmlData(
    base::WeakPtr<RenderFrameHostImpl> sender,
    const std::string& data) {}

void SavePackage::OnDidFinishedSerializingHtmlData(
    base::WeakPtr<RenderFrameHostImpl> sender) {}

const SaveItem* SavePackage::LookupSaveItemForSender(
    base::WeakPtr<RenderFrameHostImpl> sender) {}

void SavePackage::GetSavableResourceLinksForRenderFrameHost(
    RenderFrameHostImpl* rfh) {}

// Ask for all savable resource links from backend, include main frame and
// sub-frame.
void SavePackage::GetSavableResourceLinks() {}

void SavePackage::SavableResourceLinksResponse(
    RenderFrameHostImpl* sender,
    const std::vector<GURL>& resources_list,
    blink::mojom::ReferrerPtr referrer,
    const std::vector<blink::mojom::SavableSubframePtr>& subframes) {}

SaveItem* SavePackage::CreatePendingSaveItem(
    int container_frame_tree_node_id,
    int save_item_frame_tree_node_id,
    const GURL& url,
    const Referrer& referrer,
    SaveFileCreateInfo::SaveFileSource save_source) {}

void SavePackage::CreatePendingSaveItemDeduplicatingByUrl(
    int container_frame_tree_node_id,
    int save_item_frame_tree_node_id,
    const GURL& url,
    const Referrer& referrer,
    SaveFileCreateInfo::SaveFileSource save_source) {}

void SavePackage::EnqueueSavableResource(int container_frame_tree_node_id,
                                         const GURL& url,
                                         const Referrer& referrer) {}

void SavePackage::EnqueueFrame(int container_frame_tree_node_id,
                               int frame_tree_node_id,
                               const GURL& frame_original_url) {}

void SavePackage::SavableResourceLinksError(RenderFrameHostImpl* sender) {}

void SavePackage::CompleteSavableResourceLinksResponse() {}

void SavePackage::GetSaveInfo() {}

// static
base::FilePath SavePackage::CreateDirectoryOnFileThread(
    const std::u16string& title,
    const GURL& page_url,
    bool can_save_as_complete,
    const std::string& mime_type,
    const base::FilePath& website_save_dir,
    const base::FilePath& download_save_dir) {}

void SavePackage::ContinueGetSaveInfo(bool can_save_as_complete,
                                      const base::FilePath& suggested_path) {}

void SavePackage::OnPathPicked(
    SavePackagePathPickedParams params,
    SavePackageDownloadCreatedCallback download_created_callback) {}

void SavePackage::FinalizeDownloadEntry() {}

}  // namespace content