[glib-networking/mcatanzaro/proxies: 2/2] wip
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/proxies: 2/2] wip
- Date: Fri, 2 Jul 2021 20:43:20 +0000 (UTC)
commit ddee09a24b9977e75040b73740afb2b2108f55ce
Author: Michael Catanzaro <mcatanzaro redhat com>
Date: Fri Jul 2 15:43:01 2021 -0500
wip
meson.build | 19 +--
proxy/basic/basic-module.c | 65 ++++++++
proxy/basic/gbasicproxyresolver.c | 262 ++++++++++++++++++++++++++++++
proxy/basic/gbasicproxyresolver.h | 35 ++++
proxy/basic/meson.build | 38 +++++
proxy/gnome/meson.build | 2 +-
proxy/libproxy/meson.build | 2 +-
proxy/tests/{libproxy.c => environment.c} | 0
proxy/tests/meson.build | 15 +-
9 files changed, 421 insertions(+), 17 deletions(-)
---
diff --git a/meson.build b/meson.build
index 65caaa47..e275f3fa 100644
--- a/meson.build
+++ b/meson.build
@@ -169,20 +169,19 @@ if ['darwin', 'ios'].contains(host_system)
module_suffix = 'so'
endif
-if libproxy_dep.found() or gsettings_desktop_schemas_dep.found()
- proxy_test_programs = []
+proxy_test_programs = []
- if libproxy_dep.found()
- subdir('proxy/libproxy')
- endif
-
- if gsettings_desktop_schemas_dep.found()
- subdir('proxy/gnome')
- endif
+if libproxy_dep.found()
+subdir('proxy/libproxy')
+endif
- subdir('proxy/tests')
+if gsettings_desktop_schemas_dep.found()
+subdir('proxy/gnome')
endif
+subdir('proxy/basic')
+subdir('proxy/tests')
+
subdir('tls/base')
if gnutls_dep.found()
diff --git a/proxy/basic/basic-module.c b/proxy/basic/basic-module.c
new file mode 100644
index 00000000..3983bcfa
--- /dev/null
+++ b/proxy/basic/basic-module.c
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2021 Red Hat Inc.
+ *
+ * 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.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include "gbasicproxyresolver.h"
+
+
+void
+g_io_basicproxy_load (GIOModule *module)
+{
+ gchar *locale_dir;
+#ifdef G_OS_WIN32
+ gchar *base_dir;
+#endif
+
+ g_basic_proxy_resolver_register (module);
+
+#ifdef G_OS_WIN32
+ base_dir = g_win32_get_package_installation_directory_of_module (NULL);
+ locale_dir = g_build_filename (base_dir, "share", "locale", NULL);
+ g_free (base_dir);
+#else
+ locale_dir = g_strdup (LOCALE_DIR);
+#endif
+
+ bindtextdomain (GETTEXT_PACKAGE, locale_dir);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ g_free (locale_dir);
+}
+
+void
+g_io_basicproxy_unload (GIOModule *module)
+{
+}
+
+gchar **
+g_io_basicproxy_query (void)
+{
+ gchar *eps[] = {
+ G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
+ NULL
+ };
+ return g_strdupv (eps);
+}
diff --git a/proxy/basic/gbasicproxyresolver.c b/proxy/basic/gbasicproxyresolver.c
new file mode 100644
index 00000000..1379cc78
--- /dev/null
+++ b/proxy/basic/gbasicproxyresolver.c
@@ -0,0 +1,262 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2021 Red Hat Inc.
+ *
+ * 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.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gbasicproxyresolver.h"
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+struct _GBasicProxyResolver {
+ GObject parent_instance;
+};
+
+static void g_basic_proxy_resolver_iface_init (GProxyResolverInterface *iface);
+
+#ifdef GBASICPROXY_MODULE
+static void
+g_basic_proxy_resolver_class_finalize (GBasicProxyResolverClass *klass)
+{
+}
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (GBasicProxyResolver,
+ g_basic_proxy_resolver,
+ G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_PROXY_RESOLVER,
+ g_basic_proxy_resolver_iface_init))
+#else
+G_DEFINE_TYPE_EXTENDED (GBasicProxyResolver,
+ g_basic_proxy_resolver,
+ G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
+ g_basic_proxy_resolver_iface_init))
+#endif
+
+static void
+g_basic_proxy_resolver_init (GBasicProxyResolver *resolver)
+{
+}
+
+static gboolean
+g_basic_proxy_resolver_is_supported (GProxyResolver *object)
+{
+ return g_getenv ("ftp_proxy") || g_getenv ("FTP_PROXY") ||
+ g_getenv ("https_proxy") || g_getenv ("HTTPS_PROXY") ||
+ g_getenv ("http_proxy") || g_getenv ("HTTP_PROXY") ||
+ g_getenv ("no_proxy") || g_getenv ("NO_PROXY");
+}
+
+static gchar **
+proxy_results (const gchar *uri)
+{
+ gchar **proxies = g_new0 (gchar *, 2);
+ proxies[0] = g_strdup (uri);
+ return proxies;
+}
+
+static gboolean
+is_uri_ignored (const gchar *uri,
+ const gchar *ignore_pattern)
+{
+ GUri *guri = NULL;
+ GUri *ignore_guri = NULL;
+ const char *host;
+ const char *ignore_host;
+ int port;
+ int ignore_port;
+ gboolean ignored = FALSE;
+ GError *error = NULL;
+
+ guri = g_uri_parse (uri, G_URI_FLAGS_NONE, &error);
+ if (!guri)
+ {
+ g_warning ("Failed to parse URI %s: %s", uri, error->message);
+ g_error_free (error);
+ goto out;
+ }
+ host = g_uri_get_host (guri);
+ if (!host)
+ goto out;
+ port = g_uri_get_port (guri);
+
+ ignore_guri = g_uri_parse (ignore_pattern, G_URI_FLAGS_NONE, &error);
+ if (!ignore_guri)
+ {
+ g_warning ("Failed to parse URI %s: %s", ignore_pattern, error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ignore_host = g_uri_get_host (ignore_guri);
+ if (!ignore_host)
+ goto out;
+ ignore_port = g_uri_get_port (ignore_guri);
+
+ /* libproxy's no_proxy config is implement in its ignore_domain.cpp,
+ * ignore_hostname.cpp, and ignore_ip.cpp. It's smarter than ours. I've just
+ * copied the basic domain checks from libproxy's ignore_domain.cpp. (Note the
+ * glob check is *really* strict.)
+ */
+
+ /* Hostname match (domain.com or domain.com:80) */
+ if (strcmp (host, ignore_host) == 0)
+ return (ignore_port == 0 || port == ignore_port);
+
+ /* Endswith (.domain.com or .domain.com:80) */
+ if (ignore_host[0] == '.' && g_str_has_suffix (host, ignore_host))
+ return (ignore_port == 0 || port == ignore_port);
+
+ /* Glob (*.domain.com or *.domain.com:80). */
+ if (ignore_host[0] == '*' && g_str_has_suffix (host, ignore_host + 1))
+ return (ignore_port == 0 || port == ignore_port);
+
+out:
+ if (guri)
+ g_uri_unref (guri);
+ if (ignore_guri)
+ g_uri_unref (ignore_guri);
+ return ignored;
+}
+
+static gchar **
+g_basic_proxy_resolver_lookup (GProxyResolver *resolver,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gchar *scheme = g_uri_parse_scheme (uri);
+ gchar **no_proxy = NULL;
+
+ if (g_getenv ("no_proxy"))
+ no_proxy = g_strsplit (g_getenv ("no_proxy"), ",", -1);
+ else if (g_getenv ("NO_PROXY"))
+ no_proxy = g_strsplit (g_getenv ("NO_PROXY"), ",", -1);
+
+ if (no_proxy)
+ {
+ int len = g_strv_length (no_proxy);
+ gboolean ignored = FALSE;
+
+ for (int i = 0; i < len; i++)
+ {
+ if (is_uri_ignored (uri, no_proxy[i]))
+ {
+ ignored = TRUE;
+ break;
+ }
+ }
+ g_strfreev (no_proxy);
+
+ if (ignored)
+ return proxy_results ("direct://");
+ }
+
+ /* The order of precedence of the environment variables is copied from
+ * libproxy's config_envvar.cpp. We match it carefully. Note that the
+ * HTTP proxy is used for all schemes, not just HTTP.
+ */
+ if (g_ascii_strcasecmp (scheme, "ftp") == 0)
+ {
+ if (g_getenv ("ftp_proxy"))
+ return proxy_results (g_getenv ("ftp_proxy"));
+ if (g_getenv ("FTP_proxy"))
+ return proxy_results (g_getenv ("FTP_PROXY"));
+ }
+
+ if (g_ascii_strcasecmp (scheme, "https") == 0)
+ {
+ if (g_getenv ("https_proxy"))
+ return proxy_results (g_getenv ("https_proxy"));
+ if (g_getenv ("HTTPS_proxy"))
+ return proxy_results (g_getenv ("HTTPS_PROXY"));
+ }
+
+ if (g_getenv ("http_proxy"))
+ return proxy_results (g_getenv ("http_proxy"));
+
+ if (g_getenv ("HTTP_PROXY"))
+ return proxy_results (g_getenv ("HTTP_PROXY"));
+
+ return g_new0 (gchar *, 1);
+}
+
+static void
+g_basic_proxy_resolver_lookup_async (GProxyResolver *resolver,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ gchar **proxies;
+
+ proxies = g_basic_proxy_resolver_lookup (resolver, uri, cancellable, NULL);
+
+ task = g_task_new (resolver, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_basic_proxy_resolver_lookup_async);
+ g_task_set_name (task, "[glib-networking] g_basic_proxy_resolver_lookup_async");
+ g_task_set_task_data (task, g_strdup (uri), g_free);
+ g_task_set_return_on_cancel (task, TRUE);
+ g_task_return_pointer (task, proxies, (GDestroyNotify)g_strfreev);
+ g_object_unref (task);
+}
+
+static gchar **
+g_basic_proxy_resolver_lookup_finish (GProxyResolver *resolver,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, resolver), NULL);
+ g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_basic_proxy_resolver_lookup_async,
NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
+g_basic_proxy_resolver_class_init (GBasicProxyResolverClass *resolver_class)
+{
+}
+
+static void
+g_basic_proxy_resolver_iface_init (GProxyResolverInterface *iface)
+{
+ iface->is_supported = g_basic_proxy_resolver_is_supported;
+ iface->lookup = g_basic_proxy_resolver_lookup;
+ iface->lookup_async = g_basic_proxy_resolver_lookup_async;
+ iface->lookup_finish = g_basic_proxy_resolver_lookup_finish;
+}
+
+#ifdef GBASICPROXY_MODULE
+void
+g_basic_proxy_resolver_register (GIOModule *module)
+{
+ g_basic_proxy_resolver_register_type (G_TYPE_MODULE (module));
+ if (!module)
+ g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
+ g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
+ g_basic_proxy_resolver_get_type(),
+ "basic",
+ 100);
+}
+#endif
diff --git a/proxy/basic/gbasicproxyresolver.h b/proxy/basic/gbasicproxyresolver.h
new file mode 100644
index 00000000..0b10ab3f
--- /dev/null
+++ b/proxy/basic/gbasicproxyresolver.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2021 Red Hat Inc.
+ *
+ * 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.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_BASIC_PROXY_RESOLVER (g_basic_proxy_resolver_get_type ())
+
+G_DECLARE_FINAL_TYPE (GBasicProxyResolver, g_basic_proxy_resolver, G, BASIC_PROXY_RESOLVER, GObject)
+
+void g_basic_proxy_resolver_register (GIOModule *module);
+
+G_END_DECLS
diff --git a/proxy/basic/meson.build b/proxy/basic/meson.build
new file mode 100644
index 00000000..1aeed406
--- /dev/null
+++ b/proxy/basic/meson.build
@@ -0,0 +1,38 @@
+service_conf = configuration_data()
+service_conf.set('libexecdir', libexecdir)
+
+sources = files(
+ 'gbasicproxyresolver.c',
+ 'basic-module.c'
+)
+
+deps = [
+ gio_dep,
+ glib_dep,
+ gmodule_dep,
+ gobject_dep
+]
+
+module = shared_module(
+ 'giobasicproxy',
+ sources: sources,
+ include_directories: top_inc,
+ dependencies: deps,
+ c_args: '-DGBASICPROXY_MODULE',
+ link_args: module_ldflags,
+ link_depends: symbol_map,
+ name_suffix: module_suffix,
+ install: true,
+ install_dir: gio_module_dir
+)
+
+if get_option('static_modules')
+ static_library('giobasicproxy',
+ objects: module.extract_all_objects(),
+ install: true,
+ install_dir: gio_module_dir
+ )
+ pkg.generate(module)
+endif
+
+proxy_test_programs += [['environment', 'basic', deps]]
diff --git a/proxy/gnome/meson.build b/proxy/gnome/meson.build
index 278ca328..dd4bc5be 100644
--- a/proxy/gnome/meson.build
+++ b/proxy/gnome/meson.build
@@ -32,4 +32,4 @@ if get_option('static_modules')
pkg.generate(module)
endif
-proxy_test_programs += [['gnome', deps]]
+proxy_test_programs += [['gnome', 'gnome', deps]]
diff --git a/proxy/libproxy/meson.build b/proxy/libproxy/meson.build
index 038bfa1e..7a766b3d 100644
--- a/proxy/libproxy/meson.build
+++ b/proxy/libproxy/meson.build
@@ -70,4 +70,4 @@ executable(
install_dir: libexecdir
)
-proxy_test_programs += [['libproxy', deps]]
+proxy_test_programs += [['environment', 'libproxy', deps]]
diff --git a/proxy/tests/libproxy.c b/proxy/tests/environment.c
similarity index 100%
rename from proxy/tests/libproxy.c
rename to proxy/tests/environment.c
diff --git a/proxy/tests/meson.build b/proxy/tests/meson.build
index 4e0079f0..fd385876 100644
--- a/proxy/tests/meson.build
+++ b/proxy/tests/meson.build
@@ -8,20 +8,25 @@ foreach program: proxy_test_programs
test_conf.set('installed_tests_dir', installed_tests_execdir)
test_conf.set('program', program[0])
+ test_name = program[0]
+ if program[0] != program[1]
+ test_name = program[0] + '-' + program[1]
+ endif
+
if enable_installed_tests
configure_file(
input: test_template,
- output: program[0] + '.test',
+ output: test_name + '.test',
install_dir: installed_tests_metadir,
configuration: test_conf
)
endif
exe = executable(
- program[0],
+ test_name,
program[0] + '.c',
include_directories: top_inc,
- dependencies: program[1],
+ dependencies: program[2],
c_args: cflags,
install: enable_installed_tests,
install_dir: installed_tests_execdir
@@ -30,11 +35,11 @@ foreach program: proxy_test_programs
envs = [
'G_TEST_SRCDIR=' + meson.current_source_dir(),
'G_TEST_BUILDDIR=' + meson.current_build_dir(),
- 'GIO_MODULE_DIR=' + join_paths(meson.build_root(), 'proxy', program[0])
+ 'GIO_MODULE_DIR=' + join_paths(meson.build_root(), 'proxy', program[1])
]
test(
- program[0],
+ test_name,
exe,
env: envs
)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]