[gnome-builder/wip/gtk4-port: 1333/1774] libide/webkit: import some helper code from epiphany




commit 4cec82ee8e7c9a4959ef18652bed84350e8f9c93
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jun 3 14:26:02 2022 -0700

    libide/webkit: import some helper code from epiphany
    
    We need to massage the input a bit so that the url bar feels more
    natural. Thankfully, Epiphany already does this so we can copy that
    (but without the bits for search as we don't support that).

 src/libide/webkit/ide-webkit-util.c | 225 ++++++++++++++++++++++++++++++++++++
 src/libide/webkit/ide-webkit-util.h |  29 +++++
 src/libide/webkit/meson.build       |   1 +
 3 files changed, 255 insertions(+)
---
diff --git a/src/libide/webkit/ide-webkit-util.c b/src/libide/webkit/ide-webkit-util.c
new file mode 100644
index 000000000..adb18b5a5
--- /dev/null
+++ b/src/libide/webkit/ide-webkit-util.c
@@ -0,0 +1,225 @@
+/* ide-webkit-util.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* Much of the code within this file is derived from numerous files
+ * within the Epiphany web browser. The original copyright is provided
+ * below.
+ */
+/*
+ *  Copyright © 2000-2003 Marco Pesenti Gritti
+ *  Copyright © 2002 Marco Pesenti Gritti
+ *  Copyright © 2003, 2004, 2005 Christian Persch
+ *  Copyright © 2004 Crispin Flowerday
+ *  Copyright © 2004 Adam Hooper
+ *  Copyright © 2008, 2009 Gustavo Noronha Silva
+ *  Copyright © 2009, 2010, 2014 Igalia S.L.
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-webkit-util"
+
+#include "config.h"
+
+#include <libsoup/soup.h>
+
+#include "ide-webkit-util.h"
+
+#define DOMAIN_REGEX "^localhost(\\.[^[:space:]]+)?(:\\d+)?(:[0-9]+)?(/.*)?$|" \
+                     "^[^\\.[:space:]]+\\.[^\\.[:space:]]+.*$|"
+
+static char *
+string_find_and_replace (const char *haystack,
+                         const char *to_find,
+                         const char *to_repl)
+{
+  GString *str;
+
+  g_assert (haystack);
+  g_assert (to_find);
+  g_assert (to_repl);
+
+  str = g_string_new (haystack);
+  g_string_replace (str, to_find, to_repl, 0);
+  return g_string_free (str, FALSE);
+}
+
+static char *
+string_get_host_name (const char *url)
+{
+  g_autoptr(GUri) uri = NULL;
+
+  if (url == NULL ||
+      g_str_has_prefix (url, "file://") ||
+      g_str_has_prefix (url, "about:"))
+    return NULL;
+
+  uri = g_uri_parse (url, G_URI_FLAGS_NONE, NULL);
+  /* If uri is NULL it's very possible that we just got
+   * something without a scheme, let's try to prepend
+   * 'http://' */
+  if (uri == NULL) {
+    char *effective_url = g_strconcat ("http://";, url, NULL);
+    uri = g_uri_parse (effective_url, G_URI_FLAGS_NONE, NULL);
+    g_free (effective_url);
+  }
+
+  if (uri == NULL)
+    return NULL;
+
+  return g_strdup (g_uri_get_host (uri));
+}
+
+static gboolean
+address_has_web_scheme (const char *address)
+{
+  gboolean has_web_scheme;
+  int colonpos;
+
+  if (address == NULL)
+    return FALSE;
+
+  colonpos = (int)((strstr (address, ":")) - address);
+
+  if (colonpos < 0)
+    return FALSE;
+
+  has_web_scheme = !(g_ascii_strncasecmp (address, "http", colonpos) &&
+                     g_ascii_strncasecmp (address, "https", colonpos) &&
+                     g_ascii_strncasecmp (address, "file", colonpos) &&
+                     g_ascii_strncasecmp (address, "javascript", colonpos) &&
+                     g_ascii_strncasecmp (address, "data", colonpos) &&
+                     g_ascii_strncasecmp (address, "blob", colonpos) &&
+                     g_ascii_strncasecmp (address, "about", colonpos) &&
+                     g_ascii_strncasecmp (address, "gopher", colonpos) &&
+                     g_ascii_strncasecmp (address, "inspector", colonpos) &&
+                     g_ascii_strncasecmp (address, "webkit", colonpos));
+
+  return has_web_scheme;
+}
+
+static gboolean
+address_is_existing_absolute_filename (const char *address)
+{
+  g_autofree char *real_address = NULL;
+
+  if (strchr (address, '#') == NULL) {
+    real_address = g_strdup (address);
+  } else {
+    gint pos;
+
+    pos = g_strstr_len (address, -1, "#") - address;
+    real_address = g_strndup (address, pos);
+  }
+
+  return g_path_is_absolute (real_address) &&
+         g_file_test (real_address, G_FILE_TEST_EXISTS);
+}
+
+static gboolean
+is_host_with_port (const char *address)
+{
+  g_auto (GStrv) split = NULL;
+  gint64 port = 0;
+
+  if (strchr (address, ' '))
+    return FALSE;
+
+  split = g_strsplit (address, ":", -1);
+  if (g_strv_length (split) == 2)
+    port = g_ascii_strtoll (split[1], NULL, 10);
+
+  return port != 0;
+}
+
+static char *
+ensure_host_name_is_lowercase (const char *address)
+{
+  g_autofree gchar *host = string_get_host_name (address);
+  g_autofree gchar *lowercase_host = NULL;
+
+  if (host == NULL)
+    return g_strdup (address);
+
+  lowercase_host = g_utf8_strdown (host, -1);
+
+  if (strcmp (host, lowercase_host) != 0)
+    return string_find_and_replace (address, host, lowercase_host);
+  else
+    return g_strdup (address);
+}
+
+
+/* Does various normalization rules to make sure @input_address ends up
+ * with a URI scheme (e.g. absolute filenames or "localhost"), changes
+ * the URI scheme to something more appropriate when needed and lowercases
+ * the hostname.
+ */
+char *
+ide_webkit_util_normalize_address (const char *input_address)
+{
+  char *effective_address = NULL;
+  g_autofree gchar *address = NULL;
+
+  g_return_val_if_fail (input_address != NULL, NULL);
+
+  address = ensure_host_name_is_lowercase (input_address);
+
+  if (address_is_existing_absolute_filename (address))
+    return g_strconcat ("file://", address, NULL);
+
+  if (strcmp (address, "about:gpu") == 0)
+    return g_strdup ("webkit://gpu");
+
+  if (!address_has_web_scheme (address)) {
+    const char *scheme;
+
+    scheme = g_uri_peek_scheme (address);
+
+    /* Auto-prepend http:// to anything that is not
+     * one according to GLib, because it probably will be
+     * something like "google.com". Special case localhost(:port)
+     * and IP(:port), because GUri, correctly, thinks it is a
+     * URI with scheme being localhost/IP and, optionally, path
+     * being the port. Ideally we should check if we have a
+     * handler for the scheme, and since we'll fail for localhost
+     * and IP, we'd fallback to loading it as a domain. */
+    if (!scheme ||
+        !g_strcmp0 (scheme, "localhost") ||
+        g_hostname_is_ip_address (scheme) ||
+        is_host_with_port (address))
+      effective_address = g_strconcat ("http://";, address, NULL);
+  }
+
+  return effective_address ? effective_address : g_strdup (address);
+}
diff --git a/src/libide/webkit/ide-webkit-util.h b/src/libide/webkit/ide-webkit-util.h
new file mode 100644
index 000000000..2bc7bcb5c
--- /dev/null
+++ b/src/libide/webkit/ide-webkit-util.h
@@ -0,0 +1,29 @@
+/* ide-webkit-util.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+char *ide_webkit_util_normalize_address (const char *input_address);
+
+G_END_DECLS
diff --git a/src/libide/webkit/meson.build b/src/libide/webkit/meson.build
index 88b869b31..c06cc4246 100644
--- a/src/libide/webkit/meson.build
+++ b/src/libide/webkit/meson.build
@@ -12,6 +12,7 @@ libide_include_directories += include_directories('.')
 
 libide_webkit_private_sources = [
   'ide-webkit-plugin.c',
+  'ide-webkit-util.c',
   'ide-url-bar.c',
 ]
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]