From 3cb9d54c96219ba68837a6da68c57f6b7c03bbf5 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sat, 22 Oct 2016 23:30:24 +0200 Subject: [PATCH] Attempt to start dbus server from ui. --- Makefile | 9 +- README.md | 1 + src/ext-proxy.c | 185 +++++++++++++-------- src/ext-proxy.h | 2 +- src/main.c | 11 +- src/main.h | 1 + src/webextension/ext-main.c | 317 +++++++++++++++++++++--------------- 7 files changed, 309 insertions(+), 217 deletions(-) diff --git a/Makefile b/Makefile index 9cb1bf0..a554a39 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,11 @@ all: vimb options: @echo "vimb build options:" - @echo "LIBS = $(LIBS)" - @echo "CFLAGS = $(CFLAGS)" - @echo "LDFLAGS = $(LDFLAGS)" - @echo "CC = $(CC)" + @echo "LIBS = $(LIBS)" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "EXTCFLAGS = $(EXTCFLAGS)" + @echo "CC = $(CC)" vimb: $(SUBDIRS:%=%.subdir-all) diff --git a/README.md b/README.md index 087a139..3b4d73f 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ project directory. this is now available with the `RUNPREFIX` option for the make - [x] establish communication channel between the vimb instance and the now required webextension (dbus) + - [ ] use propper authorization for dbus peers 2. migrate as many of the features of the webkit1 vimb - [x] starting with custom config file `--config,-c` option - [ ] running multiple ex-commands during startup `--cmd,-C` options diff --git a/src/ext-proxy.c b/src/ext-proxy.c index 0fe07b8..2e7fb5b 100644 --- a/src/ext-proxy.c +++ b/src/ext-proxy.c @@ -24,16 +24,18 @@ #include "main.h" #include "webextension/ext-main.h" +static gboolean on_authorize_authenticated_peer(GDBusAuthObserver *observer, + GIOStream *stream, GCredentials *credentials, gpointer data); +static gboolean on_new_connection(GDBusServer *server, + GDBusConnection *connection, gpointer data); +static void on_proxy_created (GDBusProxy *proxy, GAsyncResult *result, + gpointer data); static void dbus_call(Client *c, const char *method, GVariant *param, GAsyncReadyCallback callback); static void on_editable_change_focus(GDBusConnection *connection, const char *sender_name, const char *object_path, const char *interface_name, const char *signal_name, GVariant *parameters, gpointer data); -static void on_name_appeared(GDBusConnection *connection, const char *name, - const char *owner, gpointer data); -static void on_proxy_created(GDBusProxy *new_proxy, GAsyncResult *result, - gpointer data); static void on_web_extension_page_created(GDBusConnection *connection, const char *sender_name, const char *object_path, const char *interface_name, const char *signal_name, @@ -43,34 +45,125 @@ static void on_web_extension_page_created(GDBusConnection *connection, * vimb may hold multiple clients which may use more than one webprocess and * therefore multiple webextension instances. */ extern struct Vimb vb; +static GDBusServer *dbusserver; /** - * Request the web extension to focus first editable element. - * Returns whether an focusable element was found or not. + * Initialize the dbus proxy by watching for appearing dbus name. */ -void ext_proxy_focus_input(Client *c) +const char *ext_proxy_init(void) { - dbus_call(c, "FocusInput", NULL, NULL); + char *address, *guid; + GDBusAuthObserver *observer; + GError *error = NULL; + + address = g_strdup_printf("unix:tmpdir=%s", g_get_tmp_dir()); + guid = g_dbus_generate_guid(); + observer = g_dbus_auth_observer_new(); + + g_signal_connect(observer, "authorize-authenticated-peer", + G_CALLBACK(on_authorize_authenticated_peer), NULL); + + /* Use sync call because server must be starte before the web extension + * attempt to connect */ + dbusserver = g_dbus_server_new_sync(address, G_DBUS_SERVER_FLAGS_NONE, + guid, observer, NULL, &error); + + if (error) { + g_warning("Failed to start web extension server on %s: %s", address, error->message); + g_error_free(error); + goto out; + } + + g_signal_connect(dbusserver, "new-connection", G_CALLBACK(on_new_connection), NULL); + g_dbus_server_start(dbusserver); + +out: + g_free(address); + g_free(guid); + g_object_unref(observer); + + return g_dbus_server_get_client_address(dbusserver); } -/** - * Initialize the dbus proxy by watching for appearing dbus name. - */ -void ext_proxy_init(const char *id) +/* TODO move this to a lib or somthing that can be used from ui and web + * process together */ +static gboolean on_authorize_authenticated_peer(GDBusAuthObserver *observer, + GIOStream *stream, GCredentials *credentials, gpointer data) { - char *service_name; - - service_name = g_strdup_printf("%s-%s", VB_WEBEXTENSION_SERVICE_NAME, id); - g_bus_watch_name( - G_BUS_TYPE_SESSION, - service_name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - (GBusNameAppearedCallback)on_name_appeared, + static GCredentials *own_credentials = NULL; + GError *error = NULL; + + if (!own_credentials) { + own_credentials = g_credentials_new(); + } + + if (credentials && g_credentials_is_same_user(credentials, own_credentials, &error)) { + return TRUE; + } + + if (error) { + g_warning("Failed to authorize web extension connection: %s", error->message); + g_error_free(error); + } + + return FALSE; +} + +static gboolean on_new_connection(GDBusServer *server, + GDBusConnection *connection, gpointer data) +{ + /* Create dbus proxy. */ + g_return_val_if_fail(G_IS_DBUS_CONNECTION(connection), FALSE); + + /*g_signal_connect(connection, "closed", G_CALLBACK(connection_closed_cb), NULL);*/ + + g_dbus_proxy_new(connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES|G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, NULL, + VB_WEBEXTENSION_OBJECT_PATH, + VB_WEBEXTENSION_INTERFACE, NULL, + (GAsyncReadyCallback)on_proxy_created, NULL); - g_free(service_name); + + return TRUE; +} + +static void on_proxy_created(GDBusProxy *new_proxy, GAsyncResult *result, + gpointer data) +{ + GError *error = NULL; + GDBusProxy *proxy; + GDBusConnection *connection; + + proxy = g_dbus_proxy_new_finish(result, &error); + if (!proxy) { + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_warning("Error creating web extension proxy: %s", error->message); + } + g_error_free(error); + + /* TODO cancel the dbus connection - use cancelable */ + return; + } + + connection = g_dbus_proxy_get_connection(proxy); + g_dbus_connection_signal_subscribe(connection, NULL, + VB_WEBEXTENSION_INTERFACE, "PageCreated", + VB_WEBEXTENSION_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + (GDBusSignalCallback)on_web_extension_page_created, proxy, + NULL); +} + +/** + * Request the web extension to focus first editable element. + * Returns whether an focusable element was found or not. + */ +void ext_proxy_focus_input(Client *c) +{ + dbus_call(c, "FocusInput", NULL, NULL); } /** @@ -90,6 +183,7 @@ static void dbus_call(Client *c, const char *method, GVariant *param, /* TODO add function to queue calls until the proxy connection is * established */ if (!c->dbusproxy) { + g_message("dbus_call without proxy: %s", method); return; } g_dbus_proxy_call(c->dbusproxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1, NULL, callback, c); @@ -116,53 +210,6 @@ static void on_editable_change_focus(GDBusConnection *connection, /* TODO allo strict-focus to ignore focus event for initial set focus */ } -/** - * Called when the name of the webextension appeared on the dbus session bus. - */ -static void on_name_appeared(GDBusConnection *connection, const char *name, - const char *owner, gpointer data) -{ - int flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START - | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS; - - /* Create the proxy to communicate over dbus. */ - g_dbus_proxy_new(connection, flags, NULL, name, - VB_WEBEXTENSION_OBJECT_PATH, VB_WEBEXTENSION_INTERFACE, NULL, - (GAsyncReadyCallback)on_proxy_created, NULL); -} - -/** - * Callback called when the dbus proxy is created. - */ -static void on_proxy_created(GDBusProxy *new_proxy, GAsyncResult *result, gpointer data) -{ - GDBusConnection *connection; - GDBusProxy *proxy; - GError *error = NULL; - - proxy = g_dbus_proxy_new_finish(result, &error); - connection = g_dbus_proxy_get_connection(proxy); - - if (!proxy) { - g_warning("Error creating web extension proxy: %s", error->message); - g_error_free(error); - return; - } - g_dbus_proxy_set_default_timeout(proxy, 100); - g_dbus_connection_signal_subscribe( - connection, - NULL, - VB_WEBEXTENSION_INTERFACE, - "PageCreated", - VB_WEBEXTENSION_OBJECT_PATH, - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - (GDBusSignalCallback)on_web_extension_page_created, - proxy, - NULL); -} - /** * Listen to the VerticalScroll signal of the webextension and set the scroll * percent value on the client to update the statusbar. @@ -200,7 +247,7 @@ static void on_web_extension_page_created(GDBusConnection *connection, if (p) { /* Set the dbus proxy on the right client based on page id. */ - p->dbusproxy = data; + p->dbusproxy = (GDBusProxy*)data; g_dbus_connection_signal_subscribe(connection, NULL, VB_WEBEXTENSION_INTERFACE, "VerticalScroll", diff --git a/src/ext-proxy.h b/src/ext-proxy.h index 3d6ae14..8258df9 100644 --- a/src/ext-proxy.h +++ b/src/ext-proxy.h @@ -22,8 +22,8 @@ #include "main.h" +const char *ext_proxy_init(void); void ext_proxy_focus_input(Client *c); -void ext_proxy_init(const char *id); void ext_proxy_set_header(Client *c, const char *headers); #endif /* end of include guard: _EXT_PROXY_H */ diff --git a/src/main.c b/src/main.c index d3588d7..f7187ce 100644 --- a/src/main.c +++ b/src/main.c @@ -754,20 +754,15 @@ static void on_webctx_download_started(WebKitWebContext *webctx, */ static void on_webctx_init_web_extension(WebKitWebContext *webctx, gpointer data) { - char *name; - static guint ext_count = 0; + const char *name; GVariant *vdata; /* Setup the extension directory. */ webkit_web_context_set_web_extensions_directory(webctx, EXTPREFIX); - name = g_strdup_printf("%u-%u", getpid(), ++ext_count); - ext_proxy_init(name); - - vdata = g_variant_new("(s)", name); + name = ext_proxy_init(); + vdata = g_variant_new("(ms)", name); webkit_web_context_set_web_extensions_initialization_user_data(webctx, vdata); - - g_free(name); } /** diff --git a/src/main.h b/src/main.h index 9b93c6a..212cd38 100644 --- a/src/main.h +++ b/src/main.h @@ -219,6 +219,7 @@ struct Client { guint64 page_id; /* page id of the webview */ GtkTextBuffer *buffer; GDBusProxy *dbusproxy; + GDBusServer *dbusserver; struct { /* TODO split in global setting definitions and set values on a per * client base. */ diff --git a/src/webextension/ext-main.c b/src/webextension/ext-main.c index a3a8a83..cfc8e01 100644 --- a/src/webextension/ext-main.c +++ b/src/webextension/ext-main.c @@ -27,19 +27,26 @@ #include "ext-dom.h" #include "ext-util.h" -static void add_onload_event_observers(WebKitDOMDocument *doc); -static void dbus_emit_signal(const char *name, GVariant *data); +static gboolean on_authorize_authenticated_peer(GDBusAuthObserver *observer, + GIOStream *stream, GCredentials *credentials, gpointer extension); +static void on_dbus_connection_created(GObject *source_object, + GAsyncResult *result, gpointer data); +static void add_onload_event_observers(WebKitDOMDocument *doc, + WebKitWebExtension *extension); +static void emit_page_created(GDBusConnection *connection, guint64 pageid); +static void emit_page_created_pending(GDBusConnection *connection); +static void queue_page_created_signal(guint64 pageid); +static void dbus_emit_signal(const char *name, WebKitWebExtension* extension, + GVariant *data); static void dbus_handle_method_call(GDBusConnection *conn, const char *sender, const char *object_path, const char *interface_name, const char *method, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer data); -static gboolean dbus_own_name_sync(GDBusConnection *connection, const char *name, - GBusNameOwnerFlags flags); -static void on_dbus_name_acquire(GDBusConnection *connection, const char *name, gpointer data); -static void on_editable_change_focus(WebKitDOMEventTarget *target, WebKitDOMEvent *event); -static void on_page_created(WebKitWebExtension *ext, WebKitWebPage *page, gpointer data); -static void on_web_page_document_loaded(WebKitWebPage *page, gpointer data); -static gboolean on_web_page_send_request(WebKitWebPage *page, WebKitURIRequest *request, - WebKitURIResponse *response, gpointer data); +static void on_editable_change_focus(WebKitDOMEventTarget *target, + WebKitDOMEvent *event, WebKitWebExtension *extension); +static void on_page_created(WebKitWebExtension *ext, WebKitWebPage *webpage, gpointer data); +static void on_web_page_document_loaded(WebKitWebPage *webpage, gpointer extension); +static gboolean on_web_page_send_request(WebKitWebPage *webpage, WebKitURIRequest *request, + WebKitURIResponse *response, gpointer extension); static const GDBusInterfaceVTable interface_vtable = { dbus_handle_method_call, @@ -73,6 +80,7 @@ struct Ext { GHashTable *headers; GHashTable *documents; gboolean input_focus; + GArray *page_created_signals; }; struct Ext ext = {0}; @@ -83,32 +91,79 @@ struct Ext ext = {0}; G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension *extension, GVariant *data) { - char *extid, *service_name; - g_variant_get(data, "(s)", &extid); + char *server_address; + GDBusAuthObserver *observer; - /* Get the DBus connection for the bus type. It would be a better to use - * the async g_bus_own_name for this, but this leads to cases where pages - * are created and documents are loaded before we get a name and are able - * to call to the UI process. */ - ext.connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); + g_variant_get(data, "(ms)", &server_address); + if (!server_address) { + g_warning("UI process did not start D-Bus server"); + return; + } + + g_signal_connect(extension, "page-created", G_CALLBACK(on_page_created), NULL); + + observer = g_dbus_auth_observer_new(); + g_signal_connect(observer, "authorize-authenticated-peer", + G_CALLBACK(on_authorize_authenticated_peer), extension); + + g_dbus_connection_new_for_address(server_address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, observer, NULL, + (GAsyncReadyCallback)on_dbus_connection_created, extension); + g_object_unref(observer); +} + +static gboolean on_authorize_authenticated_peer(GDBusAuthObserver *observer, + GIOStream *stream, GCredentials *credentials, gpointer extension) +{ + /* FIXME require authentication logic */ + return TRUE; +} - service_name = g_strdup_printf("%s-%s", VB_WEBEXTENSION_SERVICE_NAME, extid); +static void on_dbus_connection_created(GObject *source_object, + GAsyncResult *result, gpointer data) +{ + static GDBusNodeInfo *node_info = NULL; + GDBusConnection *connection; + GError *error = NULL; - /* Try to own name synchronously. */ - if (ext.connection && dbus_own_name_sync(ext.connection, service_name, G_BUS_NAME_OWNER_FLAGS_NONE)) { - on_dbus_name_acquire(ext.connection, service_name, extension); + if (!node_info) { + node_info = g_dbus_node_info_new_for_xml(introspection_xml, NULL); } - g_free(service_name); + connection = g_dbus_connection_new_for_address_finish(result, &error); + if (error) { + g_warning("Failed to connect to UI process: %s", error->message); + g_error_free(error); + return; + } - g_signal_connect(extension, "page-created", G_CALLBACK(on_page_created), NULL); + /* register the webextension object */ + ext.regid = g_dbus_connection_register_object( + connection, + VB_WEBEXTENSION_OBJECT_PATH, + node_info->interfaces[0], + &interface_vtable, + WEBKIT_WEB_EXTENSION(data), + NULL, + &error); + + if (!ext.regid) { + g_warning("Failed to register web extension object: %s", error->message); + g_error_free(error); + g_object_unref(connection); + return; + } + + emit_page_created_pending(connection); + ext.connection = connection; } /** * Add observers to doc event for given document and all the contained iframes * too. */ -static void add_onload_event_observers(WebKitDOMDocument *doc) +static void add_onload_event_observers(WebKitDOMDocument *doc, + WebKitWebExtension *extension) { WebKitDOMEventTarget *target; @@ -117,20 +172,72 @@ static void add_onload_event_observers(WebKitDOMDocument *doc) if (!g_hash_table_add(ext.documents, doc)) { return; } - + /* We have to use default view instead of the document itself in case this * function is called with content document of an iframe. Else the event * observing does not work. */ - target = WEBKIT_DOM_EVENT_TARGET(webkit_dom_document_get_default_view(doc)); + target = WEBKIT_DOM_EVENT_TARGET(webkit_dom_document_get_default_view(doc)); webkit_dom_event_target_add_event_listener(target, "focus", - G_CALLBACK(on_editable_change_focus), TRUE, NULL); + G_CALLBACK(on_editable_change_focus), TRUE, extension); webkit_dom_event_target_add_event_listener(target, "blur", - G_CALLBACK(on_editable_change_focus), TRUE, NULL); + G_CALLBACK(on_editable_change_focus), TRUE, extension); /* Check for focused editable elements also if they where focused before * the event observer where set up. */ /* TODO this is not needed for strict-focus=on */ - on_editable_change_focus(target, NULL); + on_editable_change_focus(target, NULL, extension); +} + +/** + * Emit the page created signal that is used in the ui process to finish the + * dbus proxy connection. + */ +static void emit_page_created(GDBusConnection *connection, guint64 pageid) +{ + GError *error = NULL; + + /* propagate the signal over dbus */ + g_dbus_connection_emit_signal(G_DBUS_CONNECTION(connection), NULL, + VB_WEBEXTENSION_OBJECT_PATH, VB_WEBEXTENSION_INTERFACE, + "PageCreated", g_variant_new("(t)", pageid), &error); + + if (error) { + g_warning("Failed to emit signal PageCreated: %s", error->message); + g_error_free(error); + } +} + +/** + * Emit queued page created signals. + */ +static void emit_page_created_pending(GDBusConnection *connection) +{ + int i; + guint64 pageid; + + if (!ext.page_created_signals) { + return; + } + + for (i = 0; i < ext.page_created_signals->len; i++) { + pageid = g_array_index(ext.page_created_signals, guint64, i); + emit_page_created(connection, pageid); + } + + g_array_free(ext.page_created_signals, TRUE); + ext.page_created_signals = NULL; +} + +/** + * Write the page id of the created page to a queue to send them to the ui + * process when the dbus connection is established. + */ +static void queue_page_created_signal(guint64 pageid) +{ + if (!ext.page_created_signals) { + ext.page_created_signals = g_array_new(FALSE, FALSE, sizeof(guint64)); + } + ext.page_created_signals = g_array_append_val(ext.page_created_signals, pageid); } /** @@ -139,11 +246,11 @@ static void add_onload_event_observers(WebKitDOMDocument *doc) * @name: Signal name to emit. * @data: GVariant value used as value for the signal or NULL. */ -static void dbus_emit_signal(const char *name, GVariant *data) +static void dbus_emit_signal(const char *name, WebKitWebExtension* extension, + GVariant *data) { GError *error = NULL; - /* Don't do anythings if the dbus connection was not established. */ if (!ext.connection) { return; } @@ -152,8 +259,6 @@ static void dbus_emit_signal(const char *name, GVariant *data) g_dbus_connection_emit_signal(ext.connection, NULL, VB_WEBEXTENSION_OBJECT_PATH, VB_WEBEXTENSION_INTERFACE, name, data, &error); - - /* check for error */ if (error) { g_warning("Failed to emit signal '%s': %s", name, error->message); g_error_free(error); @@ -165,7 +270,7 @@ static void dbus_emit_signal(const char *name, GVariant *data) */ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender, const char *object_path, const char *interface_name, const char *method, - GVariant *parameters, GDBusMethodInvocation *invocation, gpointer data) + GVariant *parameters, GDBusMethodInvocation *invocation, gpointer extension) { char *value; @@ -184,84 +289,13 @@ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender, } } -/** - * The synchronous and blocking pendent to the g_bus_own_name(). - * - * @bus_type: The type of bus to own a name on. - * @name: The well-known name to own. - * @flags: A set of flags from the #GBusNameOwnerFlags enumeration. - */ -static gboolean dbus_own_name_sync(GDBusConnection *connection, const char *name, - GBusNameOwnerFlags flags) -{ - GError *error = NULL; - guint32 request_name_reply = 0; - GVariant *result; - - result = g_dbus_connection_call_sync( - connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "RequestName", - g_variant_new("(su)", name, flags), - G_VARIANT_TYPE("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - - if (result) { - g_variant_get(result, "(u)", &request_name_reply); - g_variant_unref(result); - - if (1 == request_name_reply) { - return TRUE; - } - } else { - g_warning("Failed to acquire DBus name: %s", error->message); - g_error_free(error); - } - return FALSE; -} - -/** - * Called when the dbus name is aquired and registers our object. - */ -static void on_dbus_name_acquire(GDBusConnection *connection, const char *name, gpointer data) -{ - GError *error = NULL; - static GDBusNodeInfo *node_info = NULL; - - g_return_if_fail(G_IS_DBUS_CONNECTION(connection)); - - if (!node_info) { - node_info = g_dbus_node_info_new_for_xml(introspection_xml, NULL); - } - - /* register the webextension object */ - ext.connection = connection; - ext.regid = g_dbus_connection_register_object( - connection, - VB_WEBEXTENSION_OBJECT_PATH, - node_info->interfaces[0], - &interface_vtable, - WEBKIT_WEB_EXTENSION(data), - NULL, - &error); - - if (!ext.regid) { - g_warning("Failed to register web extension object: %s", error->message); - g_error_free(error); - } -} - /** * Callback called if a editable element changes it focus state. * Event target may be a WebKitDOMDocument (in case of iframe) or a * WebKitDOMDOMWindow. */ -static void on_editable_change_focus(WebKitDOMEventTarget *target, WebKitDOMEvent *event) +static void on_editable_change_focus(WebKitDOMEventTarget *target, + WebKitDOMEvent *event, WebKitWebExtension *extension) { gboolean input_focus; WebKitDOMDocument *doc; @@ -285,7 +319,7 @@ static void on_editable_change_focus(WebKitDOMEventTarget *target, WebKitDOMEven iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT(active); subdoc = webkit_dom_html_iframe_element_get_content_document(iframe); - add_onload_event_observers(subdoc); + add_onload_event_observers(subdoc, extension); return; } @@ -296,30 +330,36 @@ static void on_editable_change_focus(WebKitDOMEventTarget *target, WebKitDOMEven if (input_focus != ext.input_focus) { ext.input_focus = input_focus; - dbus_emit_signal("EditableChangeFocus", g_variant_new("(b)", input_focus)); + dbus_emit_signal("EditableChangeFocus", extension, + g_variant_new("(b)", input_focus)); } } /** * Callback for web extensions page-created signal. */ -static void on_page_created(WebKitWebExtension *extension, WebKitWebPage *page, gpointer data) +static void on_page_created(WebKitWebExtension *extension, WebKitWebPage *webpage, gpointer data) { + guint64 pageid = webkit_web_page_get_id(webpage); + /* Save the new created page in the extension data for later use. */ - ext.webpage = page; + ext.webpage = webpage; + if (ext.connection) { + emit_page_created(ext.connection, pageid); + } else { + queue_page_created_signal(pageid); + } - g_object_connect(page, - "signal::send-request", G_CALLBACK(on_web_page_send_request), NULL, - "signal::document-loaded", G_CALLBACK(on_web_page_document_loaded), NULL, + g_object_connect(webpage, + "signal::send-request", G_CALLBACK(on_web_page_send_request), extension, + "signal::document-loaded", G_CALLBACK(on_web_page_document_loaded), extension, NULL); - - dbus_emit_signal("PageCreated", g_variant_new("(t)", webkit_web_page_get_id(page))); } /** * Callback for web pages document-loaded signal. */ -static void on_web_page_document_loaded(WebKitWebPage *page, gpointer data) +static void on_web_page_document_loaded(WebKitWebPage *webpage, gpointer extension) { /* If there is a hashtable of known document - detroy this and create a * new hashtable. */ @@ -328,31 +368,38 @@ static void on_web_page_document_loaded(WebKitWebPage *page, gpointer data) } ext.documents = g_hash_table_new(g_direct_hash, g_direct_equal); - add_onload_event_observers(webkit_web_page_get_dom_document(page)); + add_onload_event_observers(webkit_web_page_get_dom_document(webpage), + WEBKIT_WEB_EXTENSION(extension)); } /** * Callback for web pages send-request signal. */ -static gboolean on_web_page_send_request(WebKitWebPage *page, WebKitURIRequest *request, - WebKitURIResponse *response, gpointer data) +static gboolean on_web_page_send_request(WebKitWebPage *webpage, WebKitURIRequest *request, + WebKitURIResponse *response, gpointer extension) { + char *name, *value; + SoupMessageHeaders *headers; + GHashTableIter iter; + + if (!ext.headers) { + return FALSE; + } + /* Change request headers according to the users preferences. */ - if (ext.headers) { - char *name, *value; - SoupMessageHeaders *headers; - GHashTableIter iter; - - headers = webkit_uri_request_get_http_headers(request); - g_hash_table_iter_init(&iter, ext.headers); - while (g_hash_table_iter_next(&iter, (gpointer*)&name, (gpointer*)&value)) { - /* Null value is used to indicate that the header should be - * removed completely. */ - if (value == NULL) { - soup_message_headers_remove(headers, name); - } else { - soup_message_headers_replace(headers, name, value); - } + headers = webkit_uri_request_get_http_headers(request); + if (!headers) { + return FALSE; + } + + g_hash_table_iter_init(&iter, ext.headers); + while (g_hash_table_iter_next(&iter, (gpointer*)&name, (gpointer*)&value)) { + /* Null value is used to indicate that the header should be + * removed completely. */ + if (value == NULL) { + soup_message_headers_remove(headers, name); + } else { + soup_message_headers_replace(headers, name, value); } } -- 2.20.1