From fc7689f906af62439336f0bd71802585d098594f Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Fri, 1 Jan 2010 17:53:58 +0100 Subject: [PATCH] Move DNS prefetching into the core The feature is going to be included with WebKitGTK+ and having it in the core allows us to prefetch bookmarks as well. --- extensions/dnsprefetch.c | 203 --------------------------------------- midori/midori-browser.c | 3 + midori/midori-view.c | 4 + midori/sokoke.c | 64 ++++++++++++ midori/sokoke.h | 3 + tests/magic-uri.c | 22 +++++ wscript | 1 + 7 files changed, 97 insertions(+), 203 deletions(-) delete mode 100644 extensions/dnsprefetch.c diff --git a/extensions/dnsprefetch.c b/extensions/dnsprefetch.c deleted file mode 100644 index 0667534d..00000000 --- a/extensions/dnsprefetch.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 2009 Alexander Butenko - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. -*/ - -#include - -#include "config.h" - -#include -#if HAVE_UNISTD_H - #include -#endif - -#define MAXHOSTS 50 -static gchar* hosts = NULL; -static int host_count; - -static bool -dnsprefetch_do_prefetch (const char* uri) -{ - SoupURI* s_uri; - - if (!uri) - return FALSE; - s_uri = soup_uri_new (uri); - if (!s_uri || !s_uri->host) - return FALSE; - - #if GLIB_CHECK_VERSION (2, 22, 0) - if (g_hostname_is_ip_address (s_uri->host)) - #else - if (g_ascii_isdigit (s_uri->host[0]) && g_strstr_len (s_uri->host, 4, ".")) - #endif - { - soup_uri_free (s_uri); - return FALSE; - } - if (!g_str_has_prefix (uri, "http")) - { - soup_uri_free (s_uri); - return FALSE; - } - - if (!g_regex_match_simple (s_uri->host, hosts, - G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY)) - { - SoupAddress* address; - gchar* new_hosts; - - address = soup_address_new (s_uri->host, SOUP_ADDRESS_ANY_PORT); - soup_address_resolve_async (address, 0, 0, 0, 0); - g_object_unref (address); - - if (host_count > MAXHOSTS) - { - katze_assign (hosts, g_strdup ("")); - host_count = 0; - } - host_count++; - new_hosts = g_strdup_printf ("%s|%s", hosts, s_uri->host); - katze_assign (hosts, new_hosts); - } - soup_uri_free (s_uri); - return TRUE; -} - -static void -dnsprefetch_prefetch_cb (WebKitWebView* web_view, - const gchar* title, - const char* uri, - gpointer user_data) -{ - dnsprefetch_do_prefetch (uri); -} - -static void -dnsprefetch_add_tab_cb (MidoriBrowser* browser, - MidoriView* view) -{ - GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view)); - g_signal_connect (web_view, "hovering-over-link", - G_CALLBACK (dnsprefetch_prefetch_cb), 0); -} - -static void -dnsprefetch_deactivate_cb (MidoriExtension* extension, - MidoriBrowser* browser); - -static void -dnsprefetch_add_tab_foreach_cb (MidoriView* view, - MidoriBrowser* browser) -{ - dnsprefetch_add_tab_cb (browser, view); -} - -static void -dnsprefetch_app_add_browser_cb (MidoriApp* app, - MidoriBrowser* browser, - MidoriExtension* extension) -{ - midori_browser_foreach (browser, - (GtkCallback)dnsprefetch_add_tab_foreach_cb, browser); - g_signal_connect (browser, "add-tab", - G_CALLBACK (dnsprefetch_add_tab_cb), 0); - g_signal_connect (extension, "deactivate", - G_CALLBACK (dnsprefetch_deactivate_cb), browser); -} - -static void -dnsprefetch_deactivate_tabs (MidoriView* view, - MidoriBrowser* browser) -{ - GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view)); - g_signal_handlers_disconnect_by_func ( - browser, dnsprefetch_add_tab_cb, 0); - g_signal_handlers_disconnect_by_func ( - web_view, dnsprefetch_do_prefetch, 0); -} - -static void -dnsprefetch_deactivate_cb (MidoriExtension* extension, - MidoriBrowser* browser) -{ - MidoriApp* app = midori_extension_get_app (extension); - - katze_assign (hosts, g_strdup ("")); - host_count = 0; - - g_signal_handlers_disconnect_by_func ( - extension, dnsprefetch_deactivate_cb, browser); - g_signal_handlers_disconnect_by_func ( - app, dnsprefetch_app_add_browser_cb, extension); - midori_browser_foreach (browser, (GtkCallback)dnsprefetch_deactivate_tabs, browser); - -} - -static void -dnsprefetch_activate_cb (MidoriExtension* extension, - MidoriApp* app) -{ - KatzeArray* browsers; - MidoriBrowser* browser; - guint i; - - katze_assign (hosts, g_strdup ("")); - host_count = 0; - - browsers = katze_object_get_object (app, "browsers"); - i = 0; - while ((browser = katze_array_get_nth_item (browsers, i++))) - dnsprefetch_app_add_browser_cb (app, browser, extension); - g_signal_connect (app, "add-browser", - G_CALLBACK (dnsprefetch_app_add_browser_cb), extension); - - g_object_unref (browsers); -} - -#if G_ENABLE_DEBUG -static void -dnsprefetch_parse (void) -{ - g_assert (!dnsprefetch_do_prefetch (NULL)); - g_assert (dnsprefetch_do_prefetch ("http://google.com")); - g_assert (dnsprefetch_do_prefetch ("http://google.com")); - g_assert (dnsprefetch_do_prefetch ("http://googlecom")); - g_assert (dnsprefetch_do_prefetch ("http://1kino.com")); - g_assert (dnsprefetch_do_prefetch ("http://")); - g_assert (!dnsprefetch_do_prefetch ("http:/")); - g_assert (!dnsprefetch_do_prefetch ("http")); - g_assert (!dnsprefetch_do_prefetch ("ftp://ftphost.org")); - g_assert (!dnsprefetch_do_prefetch ("http://10.0.0.1")); - g_assert (!dnsprefetch_do_prefetch ("about:blank")); - g_assert (!dnsprefetch_do_prefetch ("javascript: alert()")); -} - -void -extension_test (void) -{ - katze_assign (hosts, g_strdup ("")); - host_count = 0; - g_test_add_func ("/extensions/dnsprefetch/parse", dnsprefetch_parse); -} -#endif - -MidoriExtension* -extension_init (void) -{ - MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION, - "name", _("DNS prefetching"), - "description", _("Prefetch IP addresses of hovered links"), - "version", "0.1", - "authors", "Alexander V. Butenko ", - NULL); - g_signal_connect (extension, "activate", - G_CALLBACK (dnsprefetch_activate_cb), NULL); - - return extension; -} diff --git a/midori/midori-browser.c b/midori/midori-browser.c index 77c42c67..13f06967 100644 --- a/midori/midori-browser.c +++ b/midori/midori-browser.c @@ -2760,7 +2760,10 @@ midori_browser_menu_item_select_cb (GtkWidget* menuitem, /* This is undocumented object data, used by KatzeArrayAction. */ KatzeItem* item = g_object_get_data (G_OBJECT (menuitem), "KatzeItem"); if (item) + { tooltip = g_strdup (katze_item_get_uri (item)); + sokoke_prefetch_uri (tooltip); + } } _midori_browser_set_statusbar_text (browser, tooltip); g_free (tooltip); diff --git a/midori/midori-view.c b/midori/midori-view.c index 379fda8d..4abd75c6 100644 --- a/midori/midori-view.c +++ b/midori/midori-view.c @@ -1194,6 +1194,10 @@ webkit_web_view_hovering_over_link_cb (WebKitWebView* web_view, const gchar* link_uri, MidoriView* view) { + #if !(WEBKIT_CHECK_VERSION (2, 18, 0) && defined (HAVE_LIBSOUP_2_29_3)) + sokoke_prefetch_uri (link_uri); + #endif + katze_assign (view->link_uri, g_strdup (link_uri)); if (link_uri && g_str_has_prefix (link_uri, "mailto:")) { diff --git a/midori/sokoke.c b/midori/sokoke.c index d0f61529..89dd0b3a 100644 --- a/midori/sokoke.c +++ b/midori/sokoke.c @@ -1,6 +1,7 @@ /* Copyright (C) 2007-2009 Christian Dywan Copyright (C) 2009 Dale Whittaker + Copyright (C) 2009 Alexander Butenko This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -1521,3 +1522,66 @@ sokoke_file_chooser_dialog_new (const gchar* title, #endif return dialog; } + +/** + * sokoke_prefetch_uri: + * @uri: an URI string + * + * Attempts to prefetch the specified URI, that is + * it tries to resolve the hostname in advance. + * + * Return value: %TRUE on success + **/ +gboolean +sokoke_prefetch_uri (const char* uri) +{ + #define MAXHOSTS 50 + static gchar* hosts = NULL; + static gint host_count = G_MAXINT; + + SoupURI* s_uri; + + if (!uri) + return FALSE; + s_uri = soup_uri_new (uri); + if (!s_uri || !s_uri->host) + return FALSE; + + #if GLIB_CHECK_VERSION (2, 22, 0) + if (g_hostname_is_ip_address (s_uri->host)) + #else + if (g_ascii_isdigit (s_uri->host[0]) && g_strstr_len (s_uri->host, 4, ".")) + #endif + { + soup_uri_free (s_uri); + return FALSE; + } + if (!g_str_has_prefix (uri, "http")) + { + soup_uri_free (s_uri); + return FALSE; + } + + if (!hosts || + !g_regex_match_simple (s_uri->host, hosts, + G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY)) + { + SoupAddress* address; + gchar* new_hosts; + + address = soup_address_new (s_uri->host, SOUP_ADDRESS_ANY_PORT); + soup_address_resolve_async (address, 0, 0, 0, 0); + g_object_unref (address); + + if (host_count > MAXHOSTS) + { + katze_assign (hosts, g_strdup ("")); + host_count = 0; + } + host_count++; + new_hosts = g_strdup_printf ("%s|%s", hosts, s_uri->host); + katze_assign (hosts, new_hosts); + } + soup_uri_free (s_uri); + return TRUE; +} diff --git a/midori/sokoke.h b/midori/sokoke.h index 5f805a33..acf91ef7 100644 --- a/midori/sokoke.h +++ b/midori/sokoke.h @@ -179,4 +179,7 @@ sokoke_file_chooser_dialog_new (const gchar* title, GtkWindow* window, GtkFileChooserAction action); +gboolean +sokoke_prefetch_uri (const char* uri); + #endif /* !__SOKOKE_H__ */ diff --git a/tests/magic-uri.c b/tests/magic-uri.c index a4e58c95..5733927e 100644 --- a/tests/magic-uri.c +++ b/tests/magic-uri.c @@ -1,5 +1,6 @@ /* Copyright (C) 2008-2009 Christian Dywan + Copyright (C) 2009 Alexander Butenko This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -225,10 +226,30 @@ magic_uri_format (void) } } +static void +magic_uri_prefetch (void) +{ + g_assert (!sokoke_prefetch_uri (NULL)); + g_assert (sokoke_prefetch_uri ("http://google.com")); + g_assert (sokoke_prefetch_uri ("http://google.com")); + g_assert (sokoke_prefetch_uri ("http://googlecom")); + g_assert (sokoke_prefetch_uri ("http://1kino.com")); + g_assert (sokoke_prefetch_uri ("http://")); + g_assert (!sokoke_prefetch_uri ("http:/")); + g_assert (!sokoke_prefetch_uri ("http")); + g_assert (!sokoke_prefetch_uri ("ftp://ftphost.org")); + g_assert (!sokoke_prefetch_uri ("http://10.0.0.1")); + g_assert (!sokoke_prefetch_uri ("about:blank")); + g_assert (!sokoke_prefetch_uri ("javascript: alert()")); +} + int main (int argc, char** argv) { + /* libSoup uses threads, therefore if WebKit is built with libSoup + or Midori is using it, we need to initialize threads. */ + if (!g_thread_supported ()) g_thread_init (NULL); g_test_init (&argc, &argv, NULL); gtk_init_check (&argc, &argv); @@ -238,6 +259,7 @@ main (int argc, g_test_add_func ("/magic-uri/pseudo", magic_uri_pseudo); g_test_add_func ("/magic-uri/performance", magic_uri_performance); g_test_add_func ("/magic-uri/format", magic_uri_format); + g_test_add_func ("/magic-uri/prefetch", magic_uri_prefetch); return g_test_run (); } diff --git a/wscript b/wscript index b0e71274..e1b1b1a9 100644 --- a/wscript +++ b/wscript @@ -213,6 +213,7 @@ def configure (conf): check_pkg ('libsoup-2.4', '2.25.2') conf.define ('HAVE_LIBSOUP_2_25_2', 1) check_pkg ('libsoup-2.4', '2.27.90', False, var='LIBSOUP_2_27_90') + check_pkg ('libsoup-2.4', '2.29.3', False, var='LIBSOUP_2_29_3') check_pkg ('libxml-2.0', '2.6') if conf.env['HAVE_LIBSOUP_2_27_90']: -- 2.39.5