2022-10-05 15:23:41 +02:00
/*
* Copyright ( c ) 2020 - 2022 , Andreas Kling < kling @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# define AK_DONT_REPLACE_STD
# include "../EventLoopPluginQt.h"
# include "../FontPluginQt.h"
# include "../ImageCodecPluginLadybird.h"
# include "../RequestManagerQt.h"
# include "../Utilities.h"
# include "../WebSocketClientManagerLadybird.h"
# include <AK/LexicalPath.h>
2022-11-14 08:13:37 -05:00
# include <LibCore/ArgsParser.h>
2022-10-05 15:23:41 +02:00
# include <LibCore/EventLoop.h>
# include <LibCore/File.h>
# include <LibCore/LocalServer.h>
# include <LibCore/System.h>
2022-11-14 08:13:37 -05:00
# include <LibCore/SystemServerTakeover.h>
# include <LibIPC/ConnectionFromClient.h>
2022-10-05 15:23:41 +02:00
# include <LibMain/Main.h>
# include <LibWeb/Loader/ContentFilter.h>
# include <LibWeb/Loader/FrameLoader.h>
# include <LibWeb/Loader/ResourceLoader.h>
# include <LibWeb/WebSockets/WebSocket.h>
# include <QGuiApplication>
# include <QSocketNotifier>
# include <QTimer>
# include <WebContent/ConnectionFromClient.h>
2022-11-22 08:09:55 -05:00
# include <WebContent/PageHost.h>
2022-11-14 11:08:44 -05:00
# include <WebContent/WebDriverConnection.h>
2022-10-05 15:23:41 +02:00
static ErrorOr < void > load_content_filters ( ) ;
2022-12-04 18:43:54 +00:00
extern DeprecatedString s_serenity_resource_root ;
2022-10-05 15:23:41 +02:00
2022-11-14 08:13:37 -05:00
struct DeferredInvokerQt final : IPC : : DeferredInvoker {
virtual ~ DeferredInvokerQt ( ) = default ;
virtual void schedule ( Function < void ( ) > callback ) override
{
QTimer : : singleShot ( 0 , move ( callback ) ) ;
}
} ;
2022-12-15 09:18:52 -05:00
template < typename ClientType >
static void proxy_socket_through_notifier ( ClientType & client , QSocketNotifier & notifier )
2022-11-14 08:13:37 -05:00
{
2022-12-15 09:18:52 -05:00
notifier . setSocket ( client . socket ( ) . fd ( ) . value ( ) ) ;
2022-11-14 08:13:37 -05:00
notifier . setEnabled ( true ) ;
2022-12-15 09:18:52 -05:00
QObject : : connect ( & notifier , & QSocketNotifier : : activated , [ & client ] ( ) mutable {
client . socket ( ) . notifier ( ) - > on_ready_to_read ( ) ;
2022-11-14 08:13:37 -05:00
} ) ;
2022-12-15 09:18:52 -05:00
client . set_deferred_invoker ( make < DeferredInvokerQt > ( ) ) ;
2022-11-14 08:13:37 -05:00
}
2022-10-05 15:23:41 +02:00
ErrorOr < int > serenity_main ( Main : : Arguments arguments )
{
// NOTE: This is only used for the Core::Socket inside the IPC connection.
// FIXME: Refactor things so we can get rid of this somehow.
Core : : EventLoop event_loop ;
QGuiApplication app ( arguments . argc , arguments . argv ) ;
2022-10-07 17:08:29 -06:00
platform_init ( ) ;
2022-10-05 15:23:41 +02:00
Web : : Platform : : EventLoopPlugin : : install ( * new Ladybird : : EventLoopPluginQt ) ;
Web : : Platform : : ImageCodecPlugin : : install ( * new Ladybird : : ImageCodecPluginLadybird ) ;
Web : : ResourceLoader : : initialize ( RequestManagerQt : : create ( ) ) ;
Web : : WebSockets : : WebSocketClientManager : : initialize ( Ladybird : : WebSocketClientManagerLadybird : : create ( ) ) ;
2022-12-04 18:43:54 +00:00
Web : : FrameLoader : : set_default_favicon_path ( DeprecatedString : : formatted ( " {}/res/icons/16x16/app-browser.png " , s_serenity_resource_root ) ) ;
2022-10-05 15:23:41 +02:00
Web : : Platform : : FontPlugin : : install ( * new Ladybird : : FontPluginQt ) ;
2022-12-04 18:43:54 +00:00
Web : : FrameLoader : : set_error_page_url ( DeprecatedString : : formatted ( " file://{}/res/html/error.html " , s_serenity_resource_root ) ) ;
2022-10-05 15:23:41 +02:00
auto maybe_content_filter_error = load_content_filters ( ) ;
if ( maybe_content_filter_error . is_error ( ) )
dbgln ( " Failed to load content filters: {} " , maybe_content_filter_error . error ( ) ) ;
2022-11-14 08:13:37 -05:00
int webcontent_fd_passing_socket { - 1 } ;
2022-12-15 09:18:52 -05:00
DeprecatedString webdriver_content_ipc_path ;
2022-10-05 15:23:41 +02:00
2022-11-14 08:13:37 -05:00
Core : : ArgsParser args_parser ;
args_parser . add_option ( webcontent_fd_passing_socket , " File descriptor of the passing socket for the WebContent connection " , " webcontent-fd-passing-socket " , ' c ' , " webcontent_fd_passing_socket " ) ;
2022-12-15 09:18:52 -05:00
args_parser . add_option ( webdriver_content_ipc_path , " Path to WebDriver IPC for WebContent " , " webdriver-content-path " , 0 , " path " ) ;
2022-11-14 08:13:37 -05:00
args_parser . parse ( arguments ) ;
2022-10-05 15:23:41 +02:00
2022-12-15 09:18:52 -05:00
VERIFY ( webcontent_fd_passing_socket > = 0 ) ;
auto webcontent_socket = TRY ( Core : : take_over_socket_from_system_server ( " WebContent " sv ) ) ;
auto webcontent_client = TRY ( WebContent : : ConnectionFromClient : : try_create ( move ( webcontent_socket ) ) ) ;
webcontent_client - > set_fd_passing_socket ( TRY ( Core : : Stream : : LocalSocket : : adopt_fd ( webcontent_fd_passing_socket ) ) ) ;
2022-11-14 08:13:37 -05:00
QSocketNotifier webcontent_notifier ( QSocketNotifier : : Type : : Read ) ;
2022-12-15 09:18:52 -05:00
proxy_socket_through_notifier ( * webcontent_client , webcontent_notifier ) ;
2022-10-05 15:23:41 +02:00
2022-11-14 11:08:44 -05:00
QSocketNotifier webdriver_notifier ( QSocketNotifier : : Type : : Read ) ;
RefPtr < WebContent : : WebDriverConnection > webdriver_client ;
2022-12-15 09:18:52 -05:00
if ( ! webdriver_content_ipc_path . is_empty ( ) ) {
webdriver_client = TRY ( WebContent : : WebDriverConnection : : connect ( webcontent_client - > page_host ( ) , webdriver_content_ipc_path ) ) ;
proxy_socket_through_notifier ( * webdriver_client , webdriver_notifier ) ;
}
2022-11-14 11:08:44 -05:00
2022-10-05 15:23:41 +02:00
return app . exec ( ) ;
}
static ErrorOr < void > load_content_filters ( )
{
2022-12-04 18:43:54 +00:00
auto file_or_error = Core : : Stream : : File : : open ( DeprecatedString : : formatted ( " {}/home/anon/.config/BrowserContentFilters.txt " , s_serenity_resource_root ) , Core : : Stream : : OpenMode : : Read ) ;
2022-10-05 15:23:41 +02:00
if ( file_or_error . is_error ( ) )
2022-12-04 18:43:54 +00:00
file_or_error = Core : : Stream : : File : : open ( DeprecatedString : : formatted ( " {}/res/ladybird/BrowserContentFilters.txt " , s_serenity_resource_root ) , Core : : Stream : : OpenMode : : Read ) ;
2022-10-05 15:23:41 +02:00
if ( file_or_error . is_error ( ) )
return file_or_error . release_error ( ) ;
auto file = file_or_error . release_value ( ) ;
auto ad_filter_list = TRY ( Core : : Stream : : BufferedFile : : create ( move ( file ) ) ) ;
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
while ( TRY ( ad_filter_list - > can_read_line ( ) ) ) {
auto line = TRY ( ad_filter_list - > read_line ( buffer ) ) ;
if ( ! line . is_empty ( ) ) {
Web : : ContentFilter : : the ( ) . add_pattern ( line ) ;
}
}
return { } ;
}