2023-11-08 15:47:41 -03:00
/*
* Copyright ( c ) 2023 , Andrew Kaster < akaster @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <LibCore/ArgsParser.h>
# include <LibCore/EventLoop.h>
2024-08-01 08:03:03 -03:00
# include <LibCore/Process.h>
2023-11-08 15:47:41 -03:00
# include <LibCore/System.h>
2026-01-03 08:35:44 -03:00
# include <LibCrypto/OpenSSLForward.h>
2023-11-08 15:47:41 -03:00
# include <LibFileSystem/FileSystem.h>
# include <LibIPC/SingleServer.h>
2026-03-19 15:42:05 -03:00
# include <LibIPC/Transport.h>
2026-03-12 10:17:41 -03:00
# include <LibIPC/TransportHandle.h>
# include <LibImageDecoderClient/Client.h>
2023-11-08 15:47:41 -03:00
# include <LibMain/Main.h>
2026-03-12 10:17:41 -03:00
# include <LibRequests/RequestClient.h>
2023-11-08 15:47:41 -03:00
# include <LibWeb/Bindings/MainThreadVM.h>
2026-01-21 09:22:50 -03:00
# include <LibWeb/Fetch/Fetching/Fetching.h>
2026-02-17 15:47:21 -03:00
# include <LibWeb/HTML/UniversalGlobalScope.h>
2023-11-08 15:47:41 -03:00
# include <LibWeb/Loader/GeneratedPagesLoader.h>
# include <LibWeb/Loader/ResourceLoader.h>
# include <LibWeb/Platform/EventLoopPlugin.h>
2026-02-28 06:35:45 -03:00
# include <LibWeb/Platform/FontPlugin.h>
2025-03-27 12:31:47 -03:00
# include <LibWebView/Plugins/ImageCodecPlugin.h>
2024-11-10 12:26:07 -03:00
# include <LibWebView/Utilities.h>
2026-06-09 08:26:47 -03:00
# include <Services/RendererSandbox.h>
2023-11-08 15:47:41 -03:00
# include <WebWorker/ConnectionFromClient.h>
2026-01-03 08:35:44 -03:00
# include <openssl/thread.h>
2026-03-12 10:17:41 -03:00
static ErrorOr < void > connect_to_resource_loader ( GC : : Heap & heap , IPC : : TransportHandle const & handle ) ;
static ErrorOr < void > connect_to_image_decoder ( IPC : : TransportHandle const & handle ) ;
2023-11-08 15:47:41 -03:00
2025-04-24 02:07:09 -03:00
static ErrorOr < Web : : Bindings : : AgentType > agent_type_from_string ( StringView type )
{
if ( type = = " dedicated " sv )
return Web : : Bindings : : AgentType : : DedicatedWorker ;
if ( type = = " shared " sv )
return Web : : Bindings : : AgentType : : SharedWorker ;
if ( type = = " service " sv )
return Web : : Bindings : : AgentType : : ServiceWorker ;
return Error : : from_string_literal ( " Invalid worker type, must be one of: 'dedicated', 'shared', or 'service' " ) ;
}
2025-07-08 07:14:08 -03:00
ErrorOr < int > ladybird_main ( Main : : Arguments arguments )
2023-11-08 15:47:41 -03:00
{
2023-12-11 15:19:41 -03:00
AK : : set_rich_debug_enabled ( true ) ;
2024-01-06 17:13:59 -03:00
StringView serenity_resource_root ;
2025-04-24 02:07:09 -03:00
StringView worker_type_string ;
2026-03-19 15:42:05 -03:00
StringView mach_server_name ;
2024-07-10 08:50:21 -03:00
Vector < ByteString > certificates ;
2026-02-17 15:47:21 -03:00
bool expose_experimental_interfaces = false ;
2026-01-21 09:22:50 -03:00
bool enable_http_memory_cache = false ;
2024-08-01 08:03:03 -03:00
bool wait_for_debugger = false ;
2026-02-19 12:41:58 -03:00
bool file_origins_are_tuple_origins = false ;
2026-06-16 10:06:48 -03:00
bool disable_sandbox = false ;
2023-11-08 15:47:41 -03:00
Core : : ArgsParser args_parser ;
2024-01-06 17:13:59 -03:00
args_parser . add_option ( serenity_resource_root , " Absolute path to directory for serenity resources " , " serenity-resource-root " , ' r ' , " serenity-resource-root " ) ;
2024-07-10 08:50:21 -03:00
args_parser . add_option ( certificates , " Path to a certificate file " , " certificate " , ' C ' , " certificate " ) ;
2026-02-17 15:47:21 -03:00
args_parser . add_option ( expose_experimental_interfaces , " Expose experimental IDL interfaces " , " expose-experimental-interfaces " ) ;
2026-01-21 09:22:50 -03:00
args_parser . add_option ( enable_http_memory_cache , " Enable HTTP cache " , " enable-http-memory-cache " ) ;
2024-08-01 08:03:03 -03:00
args_parser . add_option ( wait_for_debugger , " Wait for debugger " , " wait-for-debugger " ) ;
2025-04-24 02:07:09 -03:00
args_parser . add_option ( worker_type_string , " Type of WebWorker to start (dedicated, shared, or service) " , " type " , ' t ' , " type " ) ;
2026-03-19 15:42:05 -03:00
args_parser . add_option ( mach_server_name , " Mach server name " , " mach-server-name " , 0 , " mach_server_name " ) ;
2026-02-19 12:41:58 -03:00
args_parser . add_option ( file_origins_are_tuple_origins , " Treat file:// URLs as having tuple origins " , " tuple-file-origins " ) ;
2026-06-16 10:06:48 -03:00
args_parser . add_option ( disable_sandbox , " Disable process sandboxing " , " disable-sandbox " ) ;
2025-04-24 02:07:09 -03:00
2023-11-08 15:47:41 -03:00
args_parser . parse ( arguments ) ;
2024-08-01 08:03:03 -03:00
if ( wait_for_debugger )
Core : : Process : : wait_for_debugger_and_break ( ) ;
2026-02-19 12:41:58 -03:00
if ( file_origins_are_tuple_origins )
URL : : set_file_scheme_urls_have_tuple_origins ( ) ;
2025-04-24 02:07:09 -03:00
auto worker_type = TRY ( agent_type_from_string ( worker_type_string ) ) ;
2026-06-04 14:51:47 -03:00
auto & event_loop = Core : : EventLoop : : initialize_for_current_thread ( ) ;
2024-07-05 23:41:07 -03:00
2024-11-10 12:26:07 -03:00
WebView : : platform_init ( ) ;
2023-11-08 15:47:41 -03:00
2026-01-21 09:22:50 -03:00
if ( enable_http_memory_cache )
Web : : Fetch : : Fetching : : set_http_memory_cache_enabled ( true ) ;
2026-01-03 08:35:44 -03:00
OPENSSL_TRY ( OSSL_set_max_threads ( nullptr , Core : : System : : hardware_concurrency ( ) ) ) ;
2026-02-17 15:47:21 -03:00
Web : : HTML : : UniversalGlobalScopeMixin : : set_experimental_interfaces_exposed ( expose_experimental_interfaces ) ;
2026-02-28 06:30:49 -03:00
Web : : Platform : : EventLoopPlugin : : install ( * new Web : : Platform : : EventLoopPlugin ) ;
2023-11-08 15:47:41 -03:00
2026-02-28 06:35:45 -03:00
Web : : Platform : : FontPlugin : : install ( * new Web : : Platform : : FontPlugin ( false ) ) ;
2023-11-08 15:47:41 -03:00
2025-04-24 02:07:09 -03:00
Web : : Bindings : : initialize_main_thread_vm ( worker_type ) ;
2023-11-08 15:47:41 -03:00
2026-06-16 10:06:48 -03:00
if ( ! disable_sandbox )
2026-06-09 08:26:47 -03:00
TRY ( RendererSandbox : : apply_sandbox ( { } ) ) ;
2026-03-19 15:42:05 -03:00
auto client = TRY ( IPC : : take_over_accepted_client_from_system_server < WebWorker : : ConnectionFromClient > ( mach_server_name ) ) ;
2023-11-08 15:47:41 -03:00
2026-03-12 10:17:41 -03:00
auto & heap = Web : : Bindings : : main_thread_vm ( ) . heap ( ) ;
client - > on_request_server_connection = [ & heap ] ( auto const & handle ) {
if ( auto result = connect_to_resource_loader ( heap , handle ) ; result . is_error ( ) )
dbgln ( " Failed to connect to resource loader: {} " , result . error ( ) ) ;
} ;
client - > on_image_decoder_connection = [ ] ( auto const & handle ) {
if ( auto result = connect_to_image_decoder ( handle ) ; result . is_error ( ) )
dbgln ( " Failed to connect to image decoder: {} " , result . error ( ) ) ;
} ;
2023-11-08 15:47:41 -03:00
return event_loop . exec ( ) ;
}
2026-03-12 10:17:41 -03:00
static ErrorOr < void > connect_to_resource_loader ( GC : : Heap & heap , IPC : : TransportHandle const & handle )
2025-03-27 12:31:47 -03:00
{
2026-03-12 10:17:41 -03:00
auto transport = TRY ( handle . create_transport ( ) ) ;
auto request_client = TRY ( try_make_ref_counted < Requests : : RequestClient > ( move ( transport ) ) ) ;
2025-03-27 12:31:47 -03:00
# ifdef AK_OS_WINDOWS
2026-03-12 10:17:41 -03:00
auto response = request_client - > send_sync < Messages : : RequestServer : : InitTransport > ( Core : : System : : getpid ( ) ) ;
request_client - > transport ( ) . set_peer_pid ( response - > peer_pid ( ) ) ;
2025-03-27 12:31:47 -03:00
# endif
2026-03-12 10:17:41 -03:00
if ( Web : : ResourceLoader : : is_initialized ( ) )
Web : : ResourceLoader : : the ( ) . set_client ( move ( request_client ) ) ;
else
Web : : ResourceLoader : : initialize ( heap , move ( request_client ) ) ;
2025-03-27 12:31:47 -03:00
return { } ;
}
2026-03-12 10:17:41 -03:00
static ErrorOr < void > connect_to_image_decoder ( IPC : : TransportHandle const & handle )
2023-11-08 15:47:41 -03:00
{
2026-03-12 10:17:41 -03:00
auto transport = TRY ( handle . create_transport ( ) ) ;
auto new_client = TRY ( try_make_ref_counted < ImageDecoderClient : : Client > ( move ( transport ) ) ) ;
2025-03-27 12:31:47 -03:00
# ifdef AK_OS_WINDOWS
2026-03-12 10:17:41 -03:00
auto response = new_client - > send_sync < Messages : : ImageDecoderServer : : InitTransport > ( Core : : System : : getpid ( ) ) ;
new_client - > transport ( ) . set_peer_pid ( response - > peer_pid ( ) ) ;
2025-03-27 12:31:47 -03:00
# endif
2026-03-12 10:17:41 -03:00
if ( Web : : Platform : : ImageCodecPlugin : : is_initialized ( ) )
static_cast < WebView : : ImageCodecPlugin & > ( Web : : Platform : : ImageCodecPlugin : : the ( ) ) . set_client ( move ( new_client ) ) ;
else
Web : : Platform : : ImageCodecPlugin : : install ( * new WebView : : ImageCodecPlugin ( move ( new_client ) ) ) ;
2023-11-08 15:47:41 -03:00
return { } ;
}