1,在D:develectron9srccontentpublicrowsercontent_browser_client.h 中,放着对外可以覆盖的接口
如,强制下载而不是用plugin打开:
// Called on IO or UI thread to determine whether or not to allow load and // render MHTML page from http/https URLs. virtual bool ShouldForceDownloadResource(const GURL& url, const std::string& mime_type);
D:develectron9srcextensionsshellrowsershell_content_browser_client.cc,这个类扩展自上面 class ShellContentBrowserClient : public content::ContentBrowserClient 。
D:develectron9srcelectronshellrowserelectron_browser_client.h 这个类扩展自 class ElectronBrowserClient : public content::ContentBrowserClient,public content::RenderProcessHostObserver
加入扩展命令启动开关:
void ElectronBrowserClient::AppendExtraCommandLineSwitches(
void ElectronBrowserClient::OverrideWebkitPrefs
喜好的获取:
ProcessPreferences prefs; auto* web_preferences = WebContentsPreferences::From(GetWebContentsFromProcessID(process_id)); if (web_preferences) { prefs.sandbox = web_preferences->IsEnabled(options::kSandbox); prefs.native_window_open = web_preferences->IsEnabled(options::kNativeWindowOpen); prefs.disable_popups = web_preferences->IsEnabled("disablePopups"); prefs.web_security = web_preferences->IsEnabled(options::kWebSecurity, true /* default value */); prefs.browser_context = host->GetBrowserContext();
http下载:
void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse( const GURL& response_url, network::mojom::URLResponseHead* response_head, bool* defer) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (content::download_utils::MustDownload(response_url, response_head->headers.get(), response_head->mime_type)) { return; } content::WebContents* web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id_); if (!web_contents) return; std::string extension_id = PluginUtils::GetExtensionIdForMimeType( web_contents->GetBrowserContext(), response_head->mime_type); if (extension_id.empty()) return; MimeTypesHandler::ReportUsedHandler(extension_id); std::string view_id = base::GenerateGUID(); // The string passed down to the original client with the response body. std::string payload = view_id; mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader; ignore_result(dummy_new_loader.InitWithNewPipeAndPassReceiver()); mojo::Remote<network::mojom::URLLoaderClient> new_client; mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver = new_client.BindNewPipeAndPassReceiver(); uint32_t data_pipe_size = 64U; // Provide the MimeHandlerView code a chance to override the payload. This is // the case where the resource is handled by frame-based MimeHandlerView. *defer = extensions::MimeHandlerViewAttachHelper:: OverrideBodyForInterceptedResponse( frame_tree_node_id_, response_url, response_head->mime_type, view_id, &payload, &data_pipe_size, base::BindOnce( &PluginResponseInterceptorURLLoaderThrottle::ResumeLoad, weak_factory_.GetWeakPtr())); mojo::DataPipe data_pipe(data_pipe_size); uint32_t len = static_cast<uint32_t>(payload.size()); CHECK_EQ(MOJO_RESULT_OK, data_pipe.producer_handle->WriteData( payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); new_client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle)); network::URLLoaderCompletionStatus status(net::OK); status.decoded_body_length = len; new_client->OnComplete(status); mojo::PendingRemote<network::mojom::URLLoader> original_loader; mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client; delegate_->InterceptResponse(std::move(dummy_new_loader), std::move(new_client_receiver), &original_loader, &original_client); // Make a deep copy of URLResponseHead before passing it cross-thread. auto deep_copied_response = response_head->Clone(); if (response_head->headers) { deep_copied_response->headers = base::MakeRefCounted<net::HttpResponseHeaders>( response_head->headers->raw_headers()); } auto transferrable_loader = content::mojom::TransferrableURLLoader::New(); transferrable_loader->url = GURL( extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() + base::GenerateGUID()); transferrable_loader->url_loader = std::move(original_loader); transferrable_loader->url_loader_client = std::move(original_client); transferrable_loader->head = std::move(deep_copied_response); transferrable_loader->head->intercepted_by_plugin = true; bool embedded = resource_type_ != static_cast<int>(blink::mojom::ResourceType::kMainFrame); base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent, extension_id, view_id, embedded, frame_tree_node_id_, -1 /* render_process_id */, -1 /* render_frame_id */, std::move(transferrable_loader), response_url)); }
调用堆栈:
electron.exe!net::HttpContentDisposition::ConsumeDispositionType() 行 368 在 o:nethttphttp_content_disposition.cc(368) electron.exe!net::HttpContentDisposition::Parse() 行 404 在 o:nethttphttp_content_disposition.cc(404) electron.exe!net::HttpContentDisposition::HttpContentDisposition() 行 345 在 o:nethttphttp_content_disposition.cc(345) electron.exe!content::download_utils::MustDownload() 行 45 在 o:contentrowserloaderdownload_utils_impl.cc(45) electron.exe!PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse() 行 41 在 o:chromerowserpluginsplugin_response_interceptor_url_loader_throttle.cc(41) electron.exe!blink::ThrottlingURLLoader::OnReceiveResponse() 行 567 在 o: hird_partylinkcommonloader hrottling_url_loader.cc(567) electron.exe!network::mojom::URLLoaderClientStubDispatch::Accept() 行 1126 在 o:fakeprefixgenservices etworkpublicmojomurl_loader.mojom.cc(1126) electron.exe!network::mojom::URLLoaderClientStub<mojo::RawPtrImplRefTraits<network::mojom::URLLoaderClient>>::Accept() 行 294 在 o:fakeprefixgenservices etworkpublicmojomurl_loader.mojom.h(294) electron.exe!mojo::InterfaceEndpointClient::HandleValidatedMessage() 行 554 在 o:mojopubliccppindingslibinterface_endpoint_client.cc(554) electron.exe!mojo::InterfaceEndpointClient::HandleIncomingMessageThunk::Accept() 行 140 在 o:mojopubliccppindingslibinterface_endpoint_client.cc(140) electron.exe!mojo::MessageDispatcher::Accept() 行 41 在 o:mojopubliccppindingslibmessage_dispatcher.cc(41) electron.exe!mojo::InterfaceEndpointClient::HandleIncomingMessage() 行 357 在 o:mojopubliccppindingslibinterface_endpoint_client.cc(357) electron.exe!mojo::internal::MultiplexRouter::ProcessIncomingMessage() 行 952 在 o:mojopubliccppindingslibmultiplex_router.cc(952) electron.exe!mojo::internal::MultiplexRouter::Accept() 行 620 在 o:mojopubliccppindingslibmultiplex_router.cc(620) electron.exe!mojo::MessageDispatcher::Accept() 行 41 在 o:mojopubliccppindingslibmessage_dispatcher.cc(41) electron.exe!mojo::Connector::DispatchMessageW() 行 538 在 o:mojopubliccppindingslibconnector.cc(538) electron.exe!mojo::Connector::ReadAllAvailableMessages() 行 627 在 o:mojopubliccppindingslibconnector.cc(627) electron.exe!mojo::Connector::OnHandleReadyInternal() 行 448 在 o:mojopubliccppindingslibconnector.cc(448) electron.exe!mojo::Connector::OnWatcherHandleReady() 行 408 在 o:mojopubliccppindingslibconnector.cc(408) electron.exe!base::internal::FunctorTraits<void (mojo::Connector::*)(unsigned int),void>::Invoke<void (mojo::Connector::*)(unsigned int),mojo::Connector *,unsigned int>() 行 489 在 o:aseind_internal.h(489) electron.exe!base::internal::InvokeHelper<0,void>::MakeItSo<void (mojo::Connector::*const &)(unsigned int),mojo::Connector *,unsigned int>() 行 623 在 o:aseind_internal.h(623) electron.exe!base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int),base::internal::UnretainedWrapper<mojo::Connector>>,void (unsigned int)>::RunImpl<void (mojo::Connector::*const &)(unsigned int),const std::__1::tuple<base::internal::UnretainedWrapper<mojo::Connector>> &,0>() 行 696 在 o:aseind_internal.h(696) electron.exe!base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int),base::internal::UnretainedWrapper<mojo::Connector>>,void (unsigned int)>::Run() 行 678 在 o:aseind_internal.h(678) electron.exe!base::RepeatingCallback<void (unsigned int)>::Run() 行 132 在 o:asecallback.h(132) electron.exe!mojo::SimpleWatcher::DiscardReadyState() 行 195 在 o:mojopubliccppsystemsimple_watcher.h(195) electron.exe!base::internal::FunctorTraits<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),void>::Invoke<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),const base::RepeatingCallback<void (unsigned int)> &,unsigned int,const mojo::HandleSignalsState &>() 行 389 在 o:aseind_internal.h(389) electron.exe!base::internal::InvokeHelper<0,void>::MakeItSo<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),const base::RepeatingCallback<void (unsigned int)> &,unsigned int,const mojo::HandleSignalsState &>() 行 623 在 o:aseind_internal.h(623) electron.exe!base::internal::Invoker<base::internal::BindState<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)>>,void (unsigned int, const mojo::HandleSignalsState &)>::RunImpl<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),const std::__1::tuple<base::RepeatingCallback<void (unsigned int)>> &,0>() 行 696 在 o:aseind_internal.h(696) electron.exe!base::internal::Invoker<base::internal::BindState<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)>>,void (unsigned int, const mojo::HandleSignalsState &)>::Run() 行 678 在 o:aseind_internal.h(678) electron.exe!base::RepeatingCallback<void (unsigned int, const mojo::HandleSignalsState &)>::Run() 行 132 在 o:asecallback.h(132) electron.exe!mojo::SimpleWatcher::OnHandleReady() 行 293 在 o:mojopubliccppsystemsimple_watcher.cc(293) electron.exe!base::internal::FunctorTraits<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),void>::Invoke<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>() 行 489 在 o:aseind_internal.h(489) electron.exe!base::internal::InvokeHelper<1,void>::MakeItSo<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>() 行 646 在 o:aseind_internal.h(646) electron.exe!base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunImpl<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),std::__1::tuple<base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,0,1,2,3>() 行 696 在 o:aseind_internal.h(696) electron.exe!base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunOnce() 行 665 在 o:aseind_internal.h(665) electron.exe!base::OnceCallback<void ()>::Run() 行 99 在 o:asecallback.h(99) electron.exe!base::TaskAnnotator::RunTask() 行 144 在 o:ase askcommon ask_annotator.cc(144) electron.exe!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl() 行 325 在 o:ase asksequence_manager hread_controller_with_message_pump_impl.cc(325) electron.exe!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() 行 250 在 o:ase asksequence_manager hread_controller_with_message_pump_impl.cc(250) electron.exe!base::MessagePumpForUI::DoRunLoop() 行 217 在 o:asemessage_loopmessage_pump_win.cc(217) electron.exe!base::MessagePumpWin::Run() 行 76 在 o:asemessage_loopmessage_pump_win.cc(76) electron.exe!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run() 行 433 在 o:ase asksequence_manager hread_controller_with_message_pump_impl.cc(433) electron.exe!base::RunLoop::Run() 行 124 在 o:ase un_loop.cc(124) electron.exe!content::BrowserMainLoop::MainMessageLoopRun() 行 1498 在 o:contentrowserrowser_main_loop.cc(1498) electron.exe!content::BrowserMainLoop::RunMainMessageLoopParts() 行 1060 在 o:contentrowserrowser_main_loop.cc(1060) electron.exe!content::BrowserMainRunnerImpl::Run() 行 150 在 o:contentrowserrowser_main_runner_impl.cc(150) electron.exe!content::BrowserMain() 行 47 在 o:contentrowserrowser_main.cc(47) electron.exe!content::RunBrowserProcessMain() 行 530 在 o:contentappcontent_main_runner_impl.cc(530) electron.exe!content::ContentMainRunnerImpl::RunServiceManager() 行 980 在 o:contentappcontent_main_runner_impl.cc(980) electron.exe!content::ContentMainRunnerImpl::Run() 行 879 在 o:contentappcontent_main_runner_impl.cc(879) electron.exe!content::ContentServiceManagerMainDelegate::RunEmbedderProcess() 行 52 在 o:contentappcontent_service_manager_main_delegate.cc(52) electron.exe!service_manager::Main() 行 454 在 o:servicesservice_managerembeddermain.cc(454) electron.exe!content::ContentMain() 行 20 在 o:contentappcontent_main.cc(20) electron.exe!wWinMain() 行 210 在 o:electronshellappelectron_main.cc(210) [外部代码]