1+ use std:: path:: PathBuf ;
2+
13use cef:: args:: Args ;
24use cef:: sys:: { CEF_API_VERSION_LAST , cef_resultcode_t} ;
35use cef:: {
4- App , BrowserSettings , CefString , Client , DictionaryValue , ImplCommandLine , RenderHandler , RequestContext , Settings , WindowInfo , api_hash, browser_host_create_browser_sync, execute_process,
6+ App , BrowserSettings , CefString , Client , DictionaryValue , ImplCommandLine , ImplRequestContext , RenderHandler , RequestContextSettings , SchemeHandlerFactory , Settings , WindowInfo , api_hash,
7+ browser_host_create_browser_sync, execute_process,
58} ;
69
710use super :: CefContext ;
811use super :: singlethreaded:: SingleThreadedCefContext ;
912use crate :: cef:: CefEventHandler ;
1013use crate :: cef:: consts:: { RESOURCE_DOMAIN , RESOURCE_SCHEME } ;
11- use crate :: cef:: dirs:: { cef_cache_dir , cef_data_dir } ;
14+ use crate :: cef:: dirs:: create_instance_dir ;
1215use crate :: cef:: input:: InputState ;
13- use crate :: cef:: internal:: { BrowserProcessAppImpl , BrowserProcessClientImpl , RenderHandlerImpl , RenderProcessAppImpl } ;
16+ use crate :: cef:: internal:: { BrowserProcessAppImpl , BrowserProcessClientImpl , RenderHandlerImpl , RenderProcessAppImpl , SchemeHandlerFactoryImpl } ;
1417
1518pub ( crate ) struct CefContextBuilder < H : CefEventHandler > {
1619 pub ( crate ) args : Args ,
@@ -61,33 +64,37 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
6164
6265 #[ cfg( target_os = "macos" ) ]
6366 pub ( crate ) fn initialize ( self , event_handler : H ) -> Result < impl CefContext , InitError > {
67+ let instance_dir = create_instance_dir ( ) ;
68+
6469 let settings = Settings {
6570 windowless_rendering_enabled : 1 ,
6671 multi_threaded_message_loop : 0 ,
6772 external_message_pump : 1 ,
68- root_cache_path : cef_data_dir ( ) . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
69- cache_path : cef_cache_dir ( ) . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
73+ root_cache_path : instance_dir . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
74+ cache_path : CefString :: from ( "" ) ,
7075 ..Default :: default ( )
7176 } ;
7277
7378 self . initialize_inner ( & event_handler, settings) ?;
7479
75- create_browser ( event_handler)
80+ create_browser ( event_handler, instance_dir )
7681 }
7782
7883 #[ cfg( not( target_os = "macos" ) ) ]
7984 pub ( crate ) fn initialize ( self , event_handler : H ) -> Result < impl CefContext , InitError > {
85+ let instance_dir = create_instance_dir ( ) ;
86+
8087 let settings = Settings {
8188 windowless_rendering_enabled : 1 ,
8289 multi_threaded_message_loop : 1 ,
83- root_cache_path : cef_data_dir ( ) . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
84- cache_path : cef_cache_dir ( ) . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
90+ root_cache_path : instance_dir . to_str ( ) . map ( CefString :: from) . unwrap ( ) ,
91+ cache_path : CefString :: from ( "" ) ,
8592 ..Default :: default ( )
8693 } ;
8794
8895 self . initialize_inner ( & event_handler, settings) ?;
8996
90- super :: multithreaded:: run_on_ui_thread ( move || match create_browser ( event_handler) {
97+ super :: multithreaded:: run_on_ui_thread ( move || match create_browser ( event_handler, instance_dir ) {
9198 Ok ( context) => {
9299 super :: multithreaded:: CONTEXT . with ( |b| {
93100 * b. borrow_mut ( ) = Some ( context) ;
@@ -103,10 +110,10 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
103110 }
104111
105112 fn initialize_inner ( self , event_handler : & H , settings : Settings ) -> Result < ( ) , InitError > {
106- let mut cef_app = App :: new ( BrowserProcessAppImpl :: new ( event_handler. clone ( ) ) ) ;
107- let result = cef:: initialize ( Some ( self . args . as_main_args ( ) ) , Some ( & settings) , Some ( & mut cef_app) , std:: ptr:: null_mut ( ) ) ;
108113 // Attention! Wrapping this in an extra App is necessary, otherwise the program still compiles but segfaults
114+ let mut cef_app = App :: new ( BrowserProcessAppImpl :: new ( event_handler. clone ( ) ) ) ;
109115
116+ let result = cef:: initialize ( Some ( self . args . as_main_args ( ) ) , Some ( & settings) , Some ( & mut cef_app) , std:: ptr:: null_mut ( ) ) ;
110117 if result != 1 {
111118 let cef_exit_code = cef:: get_exit_code ( ) as u32 ;
112119 if cef_exit_code == cef_resultcode_t:: CEF_RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED as u32 {
@@ -118,12 +125,10 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
118125 }
119126}
120127
121- fn create_browser < H : CefEventHandler > ( event_handler : H ) -> Result < SingleThreadedCefContext , InitError > {
128+ fn create_browser < H : CefEventHandler > ( event_handler : H , instance_dir : PathBuf ) -> Result < SingleThreadedCefContext , InitError > {
122129 let render_handler = RenderHandler :: new ( RenderHandlerImpl :: new ( event_handler. clone ( ) ) ) ;
123130 let mut client = Client :: new ( BrowserProcessClientImpl :: new ( render_handler, event_handler. clone ( ) ) ) ;
124131
125- let url = CefString :: from ( format ! ( "{RESOURCE_SCHEME}://{RESOURCE_DOMAIN}/" ) . as_str ( ) ) ;
126-
127132 let window_info = WindowInfo {
128133 windowless_rendering_enabled : 1 ,
129134 #[ cfg( feature = "accelerated_paint" ) ]
@@ -137,19 +142,37 @@ fn create_browser<H: CefEventHandler>(event_handler: H) -> Result<SingleThreaded
137142 ..Default :: default ( )
138143 } ;
139144
145+ let Some ( mut incognito_request_context) = cef:: request_context_create_context (
146+ Some ( & RequestContextSettings {
147+ persist_session_cookies : 0 ,
148+ cache_path : CefString :: from ( "" ) ,
149+ ..Default :: default ( )
150+ } ) ,
151+ Option :: < & mut cef:: RequestContextHandler > :: None ,
152+ ) else {
153+ return Err ( InitError :: RequestContextCreationFailed ) ;
154+ } ;
155+
156+ let mut scheme_handler_factory = SchemeHandlerFactory :: new ( SchemeHandlerFactoryImpl :: new ( event_handler. clone ( ) ) ) ;
157+ incognito_request_context. clear_scheme_handler_factories ( ) ;
158+ incognito_request_context. register_scheme_handler_factory ( Some ( & CefString :: from ( RESOURCE_SCHEME ) ) , Some ( & CefString :: from ( RESOURCE_DOMAIN ) ) , Some ( & mut scheme_handler_factory) ) ;
159+
160+ let url = CefString :: from ( format ! ( "{RESOURCE_SCHEME}://{RESOURCE_DOMAIN}/" ) . as_str ( ) ) ;
161+
140162 let browser = browser_host_create_browser_sync (
141163 Some ( & window_info) ,
142164 Some ( & mut client) ,
143165 Some ( & url) ,
144166 Some ( & settings) ,
145167 Option :: < & mut DictionaryValue > :: None ,
146- Option :: < & mut RequestContext > :: None ,
168+ Some ( & mut incognito_request_context ) ,
147169 ) ;
148170
149171 if let Some ( browser) = browser {
150172 Ok ( SingleThreadedCefContext {
151173 browser,
152174 input_state : InputState :: default ( ) ,
175+ instance_dir,
153176 } )
154177 } else {
155178 tracing:: error!( "Failed to create browser" ) ;
@@ -171,6 +194,8 @@ pub(crate) enum InitError {
171194 InitializationFailed ( u32 ) ,
172195 #[ error( "Browser creation failed" ) ]
173196 BrowserCreationFailed ,
197+ #[ error( "Request context creation failed" ) ]
198+ RequestContextCreationFailed ,
174199 #[ error( "Another instance is already running" ) ]
175200 AlreadyRunning ,
176201}
0 commit comments