[glib-networking/mcatanzaro/pacrunner] wip




commit a51fd4ca88c0c9716b0b2417419850aafba5ab81
Author: Michael Catanzaro <mcatanzaro redhat com>
Date:   Thu Feb 17 16:02:06 2022 -0600

    wip

 meson.build                                        |   6 +-
 meson_options.txt                                  |   1 +
 proxy/libproxy/meson.build                         |  37 ----
 proxy/meson.build                                  |   4 +
 .../glib-pacrunner.service.in                      |   2 +-
 proxy/pacrunner/meson.build                        |  54 +++++
 .../org.gtk.GLib.PACRunner.service.in              |   2 +-
 .../pacrunner-service.c}                           |  68 +++---
 proxy/pacrunner/pacrunner-worker.c                 | 223 +++++++++++++++++++
 proxy/pacrunner/pacutils.h                         | 242 +++++++++++++++++++++
 tls/base/meson.build                               |   3 +-
 tls/gnutls/gtlsdatabase-gnutls.c                   |   1 -
 tls/base/gtlshttp.c => util/ghttp.c                |  10 +-
 tls/base/gtlshttp.h => util/ghttp.h                |   6 +-
 util/meson.build                                   |  12 +
 15 files changed, 580 insertions(+), 91 deletions(-)
---
diff --git a/meson.build b/meson.build
index 99dbeb13..9d82b99b 100644
--- a/meson.build
+++ b/meson.build
@@ -73,6 +73,9 @@ libproxy_dep = dependency('libproxy-1.0', version: '>= 0.3.1', required: get_opt
 # *** Checks for GNOME      ***
 gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas', required: get_option('gnome_proxy'))
 
+# *** Checks for WebKitGTK  ***
+javascriptcoregtk_dep = dependency('javascriptcoregtk-4.1', required: get_option('pacrunner'))
+
 backends = []
 
 # *** Check for dl          ***
@@ -169,9 +172,10 @@ endif
 
 proxy_test_programs = []
 
-subdir('po')
+subdir('util')
 subdir('proxy')
 subdir('tls')
+subdir('po')
 
 # Will automatically pick it up from the cross file if defined
 gio_querymodules = find_program('gio-querymodules', required : false)
diff --git a/meson_options.txt b/meson_options.txt
index aaf62274..5d0dc74d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -5,5 +5,6 @@ option('gnutls', type: 'feature', value: 'auto', description: 'support for GnuTL
 option('openssl', type: 'feature', value: 'disabled', description: 'support for OpenSSL networking 
configration')
 option('libproxy', type: 'feature', value: 'auto', description: 'support for libproxy proxy configration')
 option('gnome_proxy', type: 'feature', value: 'auto', description: 'support for GNOME desktop proxy 
configuration')
+option('pacrunner', type: 'feature', value: 'auto', description: 'support for web proxy autoconfig')
 option('installed_tests', type: 'boolean', value: false, description: 'enable installed tests')
 option('static_modules', type: 'boolean', value: false, description: 'build static modules')
diff --git a/proxy/libproxy/meson.build b/proxy/libproxy/meson.build
index 7a766b3d..713683f7 100644
--- a/proxy/libproxy/meson.build
+++ b/proxy/libproxy/meson.build
@@ -1,26 +1,3 @@
-service_conf = configuration_data()
-service_conf.set('libexecdir', libexecdir)
-
-service = 'org.gtk.GLib.PACRunner.service'
-
-configure_file(
-  input: service + '.in',
-  output: service,
-  install: true,
-  install_dir: join_paths(datadir, 'dbus-1', 'services'),
-  configuration: service_conf
-)
-
-service = 'glib-pacrunner.service'
-
-configure_file(
-  input: service + '.in',
-  output: service,
-  install: true,
-  install_dir: join_paths('lib', 'systemd', 'user'),
-  configuration: service_conf
-)
-
 sources = files(
   'glibproxyresolver.c',
   'libproxy-module.c'
@@ -56,18 +33,4 @@ if get_option('static_modules')
   pkg.generate(module)
 endif
 
-sources = files(
-  'glibproxyresolver.c',
-  'glibpacrunner.c'
-)
-
-executable(
-  'glib-pacrunner',
-  sources,
-  include_directories: top_inc,
-  dependencies: deps,
-  install: true,
-  install_dir: libexecdir
-)
-
 proxy_test_programs += [['environment', 'libproxy', deps]]
diff --git a/proxy/meson.build b/proxy/meson.build
index c6384525..5ab32009 100644
--- a/proxy/meson.build
+++ b/proxy/meson.build
@@ -12,4 +12,8 @@ if not ['windows'].contains(host_system)
   subdir('environment')
 endif
 
+if javascriptcoregtk_dep.found()
+  subdir('pacrunner')
+endif
+
 subdir('tests')
diff --git a/proxy/libproxy/glib-pacrunner.service.in b/proxy/pacrunner/glib-pacrunner.service.in
similarity index 70%
rename from proxy/libproxy/glib-pacrunner.service.in
rename to proxy/pacrunner/glib-pacrunner.service.in
index 0f289de9..6f977d85 100644
--- a/proxy/libproxy/glib-pacrunner.service.in
+++ b/proxy/pacrunner/glib-pacrunner.service.in
@@ -4,4 +4,4 @@ Description=GLib proxy auto-configuration service
 [Service]
 Type=dbus
 BusName=org.gtk.GLib.PACRunner
-ExecStart=@libexecdir@/glib-pacrunner
+ExecStart=@libexecdir@/glib-pacrunner-service
diff --git a/proxy/pacrunner/meson.build b/proxy/pacrunner/meson.build
new file mode 100644
index 00000000..1f513a35
--- /dev/null
+++ b/proxy/pacrunner/meson.build
@@ -0,0 +1,54 @@
+service_conf = configuration_data()
+service_conf.set('libexecdir', libexecdir)
+
+service = 'org.gtk.GLib.PACRunner.service'
+
+configure_file(
+  input: service + '.in',
+  output: service,
+  install: true,
+  install_dir: join_paths(datadir, 'dbus-1', 'services'),
+  configuration: service_conf
+)
+
+service = 'glib-pacrunner.service'
+
+configure_file(
+  input: service + '.in',
+  output: service,
+  install: true,
+  install_dir: join_paths('lib', 'systemd', 'user'),
+  configuration: service_conf
+)
+
+service_deps = [
+  gio_dep,
+  glib_dep,
+  gobject_dep,
+]
+
+executable(
+  'glib-pacrunner-service',
+  'pacrunner-service.c',
+  include_directories: top_inc,
+  dependencies: service_deps,
+  install: true,
+  install_dir: libexecdir
+)
+
+worker_deps = [
+  gio_dep,
+  glib_dep,
+  gobject_dep,
+  javascriptcoregtk_dep,
+  util_dep
+]
+
+executable(
+  'glib-pacrunner-worker',
+  'pacrunner-worker.c',
+  include_directories: top_inc,
+  dependencies: worker_deps,
+  install: true,
+  install_dir: libexecdir
+)
diff --git a/proxy/libproxy/org.gtk.GLib.PACRunner.service.in 
b/proxy/pacrunner/org.gtk.GLib.PACRunner.service.in
similarity index 66%
rename from proxy/libproxy/org.gtk.GLib.PACRunner.service.in
rename to proxy/pacrunner/org.gtk.GLib.PACRunner.service.in
index f1bd6990..d8230f8f 100644
--- a/proxy/libproxy/org.gtk.GLib.PACRunner.service.in
+++ b/proxy/pacrunner/org.gtk.GLib.PACRunner.service.in
@@ -1,4 +1,4 @@
 [D-BUS Service]
 Name=org.gtk.GLib.PACRunner
-Exec=@libexecdir@/glib-pacrunner
+Exec=@libexecdir@/glib-pacrunner-service
 SystemdService=glib-pacrunner.service
diff --git a/proxy/libproxy/glibpacrunner.c b/proxy/pacrunner/pacrunner-service.c
similarity index 74%
rename from proxy/libproxy/glibpacrunner.c
rename to proxy/pacrunner/pacrunner-service.c
index c72304fb..dc8fb91c 100644
--- a/proxy/libproxy/glibpacrunner.c
+++ b/proxy/pacrunner/pacrunner-service.c
@@ -2,7 +2,7 @@
 /*
  * GIO - GLib Input, Output and Streaming Library
  *
- * Copyright 2011 Red Hat, Inc.
+ * Copyright © 2011, 2022 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
@@ -21,10 +21,8 @@
 
 #include "config.h"
 
-#include <stdlib.h>
-
 #include <gio/gio.h>
-#include "glibproxyresolver.h"
+#include <stdlib.h>
 
 static const gchar introspection_xml[] =
   "<node>"
@@ -37,9 +35,9 @@ static const gchar introspection_xml[] =
   "  </interface>"
   "</node>";
 
-static GProxyResolver *resolver;
 static GMainLoop *loop;
 
+#if 0
 static void
 got_proxies (GObject      *source,
              GAsyncResult *result,
@@ -49,7 +47,7 @@ got_proxies (GObject      *source,
   gchar **proxies;
   GError *error = NULL;
 
-  proxies = g_proxy_resolver_lookup_finish (resolver, result, &error);
+  proxies = NULL; /* FIXME */
   if (error)
     g_dbus_method_invocation_take_error (invocation, error);
   else
@@ -59,6 +57,24 @@ got_proxies (GObject      *source,
       g_strfreev (proxies);
     }
 }
+#endif
+
+static void
+handle_lookup (const char            *pac_url,
+               const char            *lookup_url,
+               GDBusMethodInvocation *invocation)
+{
+  if (g_ascii_strncasecmp (pac_url, "http:", 5) &&
+      g_ascii_strncasecmp (pac_url, "https:", 6) &&
+      g_ascii_strncasecmp (pac_url, "file:", 5))
+    {
+      g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                                             "PAC URL %s has unsupported protocol", pac_url);
+      return;
+    }
+
+  /* FIXME: do something here would be good */
+}
 
 static void
 handle_method_call (GDBusConnection       *connection,
@@ -70,22 +86,10 @@ handle_method_call (GDBusConnection       *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
 {
-  const gchar *pac_url, *lookup_url;
+  const char *pac_url, *lookup_url;
 
   g_variant_get (parameters, "(&s&s)", &pac_url, &lookup_url);
-
-  if (!g_ascii_strncasecmp (pac_url, "http", 4) ||
-      !g_ascii_strncasecmp (pac_url, "file:", 5))
-    {
-      gchar *libproxy_url = g_strdup_printf ("pac+%s", pac_url);
-      g_setenv ("http_proxy", libproxy_url, TRUE);
-      g_free (libproxy_url);
-    }
-  else
-    g_setenv ("http_proxy", "wpad://", TRUE);
-
-  g_proxy_resolver_lookup_async (resolver, lookup_url,
-                                 NULL, got_proxies, invocation);
+  handle_lookup (pac_url, lookup_url, invocation);
 }
 
 static const GDBusInterfaceVTable interface_vtable =
@@ -135,26 +139,7 @@ main (int argc, char *argv[])
 {
   int owner_id;
 
-  /* Unset variables that would make libproxy try to use gconf or ksettings */
-  g_unsetenv ("GNOME_DESKTOP_SESSION_ID");
-  g_unsetenv ("DESKTOP_SESSION");
-  g_unsetenv ("KDE_FULL_SESSION");
-
-  /* Unset variables that libproxy would look at if it were smarter, and which
-   * it might possibly look at in the future. Just covering our bases. */
-  g_unsetenv ("XDG_CURRENT_DESKTOP");
-
-  /* Unset static proxy settings */
-  g_unsetenv ("http_proxy");
-  g_unsetenv ("HTTP_PROXY");
-  g_unsetenv ("https_proxy");
-  g_unsetenv ("HTTPS_PROXY");
-  g_unsetenv ("ftp_proxy");
-  g_unsetenv ("FTP_PROXY");
-  g_unsetenv ("no_proxy");
-  g_unsetenv ("NO_PROXY");
-
-  resolver = g_object_new (G_TYPE_LIBPROXY_RESOLVER, NULL);
+/* FIXME: should add --help and --version */
 
   owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                              "org.gtk.GLib.PACRunner",
@@ -169,5 +154,8 @@ main (int argc, char *argv[])
   g_main_loop_run (loop);
 
   g_bus_unown_name (owner_id);
+
+  g_main_loop_unref (loop);
+
   return 0;
 }
diff --git a/proxy/pacrunner/pacrunner-worker.c b/proxy/pacrunner/pacrunner-worker.c
new file mode 100644
index 00000000..d205f191
--- /dev/null
+++ b/proxy/pacrunner/pacrunner-worker.c
@@ -0,0 +1,223 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2011, 2022 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 "ghttp.h"
+#include "pacutils.h"
+#include <gio/gio.h>
+#include <jsc/jsc.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static char *
+dns_resolve (const char *hostname)
+{
+  GResolver *resolver = g_resolver_get_default ();
+  GList *addresses;
+  char *first_address;
+  GError *error = NULL;
+
+  addresses = g_resolver_lookup_by_name (resolver,
+                                         hostname,
+                                         NULL,
+                                         &error);
+  if (error) {
+    g_warning ("Failed to resolve %s: %s", hostname, error->message);
+    g_error_free (error);
+    return NULL;
+  }
+
+  first_address = g_inet_address_to_string (addresses->data);
+  g_resolver_free_addresses (addresses);
+  return first_address;
+}
+
+static char *
+my_ip_address (void)
+{
+  char hostname[HOST_NAME_MAX + 1];
+
+  if (gethostname (hostname, sizeof (hostname)) == -1)
+    {
+      g_warning ("Failed to get system hostname: %s", g_strerror (errno));
+      return NULL;
+    }
+
+  return dns_resolve (hostname);
+}
+
+static char *
+download_pac (const char  *pac_url,
+              GError     **error)
+{
+  GInputStream *pac;
+  GByteArray *bytes;
+  guchar buffer[2048];
+  gssize n_read;
+  char *result = NULL;
+
+  pac = g_request_uri (pac_url, NULL, error);
+  if (!pac)
+    return NULL;
+
+  bytes = g_byte_array_sized_new (sizeof (buffer));
+  do
+    {
+      n_read = g_input_stream_read (pac, buffer, sizeof (buffer),
+                                    NULL, error);
+      if (n_read == -1)
+        goto out;
+      g_byte_array_append (bytes, buffer, n_read);
+    } while (n_read > 0);
+
+  result = (char *)g_byte_array_free (bytes, FALSE);
+
+out:
+  g_object_unref (pac);
+  return result;
+}
+
+static char *
+evaluate_pac (const char  *pac,
+              const char  *lookup_url,
+              GError     **error)
+{
+  JSCContext *context;
+  JSCValue *value = NULL;
+  char *statement = NULL;
+  char *result = NULL;
+  JSCException *exception = NULL;
+
+  context = jsc_context_new ();
+  value = jsc_value_new_function (context,
+                                  "dnsResolve",
+                                  G_CALLBACK (dns_resolve), NULL, NULL,
+                                  G_TYPE_STRING, 1,
+                                  G_TYPE_STRING);
+  jsc_context_set_value (context, "dnsResolve", value);
+  g_object_unref (value);
+
+  value = jsc_value_new_function (context,
+                                  "myIpAddress",
+                                  G_CALLBACK (my_ip_address), NULL, NULL,
+                                  G_TYPE_STRING, 0);
+  jsc_context_set_value (context, "dnsResolve", value);
+  g_object_unref (value);
+
+  jsc_context_check_syntax (context,
+                            JAVASCRIPT_ROUTINES, -1,
+                            JSC_CHECK_SYNTAX_MODE_SCRIPT,
+                            NULL, 0, &exception);
+  if (exception)
+    g_error ("Fatal: pacrunner JS failed syntax sanity check: %s", jsc_exception_report (exception));
+  value = jsc_context_evaluate (context, JAVASCRIPT_ROUTINES, -1);
+  g_object_unref (value);
+
+  jsc_context_check_syntax (context,
+                            pac, -1,
+                            JSC_CHECK_SYNTAX_MODE_SCRIPT,
+                            NULL, 0, &exception);
+  if (exception)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Syntax error in proxy autoconfig script: %s", jsc_exception_report (exception));
+      g_object_unref (exception);
+      goto out;
+    }
+  value = jsc_context_evaluate (context, pac, -1);
+  g_object_unref (value);
+
+/* FIXME: need to URL encode here */
+/* FIXME: second URL should be host */
+/* FIXME: use a helper function for check syntax + evaluate */
+  statement = g_strdup_printf ("FindProxyForURL('%s', '%s');", lookup_url, lookup_url);
+  jsc_context_check_syntax (context,
+                            statement, -1,
+                            JSC_CHECK_SYNTAX_MODE_SCRIPT,
+                            NULL, 0, &exception);
+  if (exception)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Syntax error in script \"%s\": %s", statement, jsc_exception_report (exception));
+      g_object_unref (exception);
+      goto out;
+    }
+  value = jsc_context_evaluate (context, pac, -1);
+  if (!jsc_value_is_string (value))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Proxy autoconfig script result '%s' is not a string", jsc_value_to_string (value));
+      g_clear_object (&value);
+    }
+
+out:
+  if (value)
+    {
+      result = jsc_value_to_string (value);
+      g_object_unref (value);
+    }
+  g_free (statement);
+  g_object_unref (context);
+  return result;
+}
+
+int
+main (int argc, char *argv[])
+{
+  const char *pac_url;
+  const char *lookup_url;
+  char *pac = NULL;
+  int exit_status = 1;
+  GError *error = NULL;
+
+/* FIXME: GOptionContext. should add some --help and some --version etc. */
+if (argc != 2)
+{
+g_warning ("You're doing it wrong.");
+return 1;
+}
+pac_url = argv[0];
+lookup_url = argv[1];
+
+  pac = download_pac (pac_url, &error);
+  if (!pac)
+    {
+      g_warning ("Failed to download proxy autoconfig script %s: %s", pac_url, error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  evaluate_pac (pac, lookup_url, &error);
+  if (error)
+    {
+      g_warning ("Failed to resolve proxy for URL %s using proxy autoconfig script %s: %s",
+                 lookup_url, pac_url, error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  exit_status = 0;
+
+out:
+  g_free (pac);
+  return exit_status;
+}
diff --git a/proxy/pacrunner/pacutils.h b/proxy/pacrunner/pacutils.h
new file mode 100644
index 00000000..38260140
--- /dev/null
+++ b/proxy/pacrunner/pacutils.h
@@ -0,0 +1,242 @@
+/* 
+ * The following Javascript code was taken from Mozilla (http://www.mozilla.org)
+ * and is licensed according to the LGPLv2.1+.  Below is the original copyright 
+ * header as contained in the source file (nsProxyAutoConfig.js)
+ */
+ 
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Akhil Arora <akhil arora sun com>
+ *   Tomi Leppikangas <Tomi Leppikangas oulu fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the NPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#define JAVASCRIPT_ROUTINES \
+"function dnsDomainIs(host, domain) {\n" \
+"    return (host.length >= domain.length &&\n" \
+"            host.substring(host.length - domain.length) == domain);\n" \
+"}\n" \
+"function dnsDomainLevels(host) {\n" \
+"    return host.split('.').length-1;\n" \
+"}\n" \
+"function convert_addr(ipchars) {\n" \
+"    var bytes = ipchars.split('.');\n" \
+"    var result = ((bytes[0] & 0xff) << 24) |\n" \
+"                 ((bytes[1] & 0xff) << 16) |\n" \
+"                 ((bytes[2] & 0xff) << 8) |\n" \
+"                  (bytes[3] & 0xff);\n" \
+"    return result;\n" \
+"}\n" \
+"function isInNet(ipaddr, pattern, maskstr) {\n"\
+"    var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n"\
+"    if (test == null) {\n"\
+"        ipaddr = dnsResolve(ipaddr);\n"\
+"        if (ipaddr == null)\n"\
+"            return false;\n"\
+"    } else if (test[1] > 255 || test[2] > 255 || \n"\
+"               test[3] > 255 || test[4] > 255) {\n"\
+"        return false;    // not an IP address\n"\
+"    }\n"\
+"    var host = convert_addr(ipaddr);\n"\
+"    var pat  = convert_addr(pattern);\n"\
+"    var mask = convert_addr(maskstr);\n"\
+"    return ((host & mask) == (pat & mask));\n"\
+"    \n"\
+"}\n"\
+"function isPlainHostName(host) {\n" \
+"    return (host.search('\\\\.') == -1);\n" \
+"}\n" \
+"function isResolvable(host) {\n" \
+"    var ip = dnsResolve(host);\n" \
+"    return (ip != null);\n" \
+"}\n" \
+"function localHostOrDomainIs(host, hostdom) {\n" \
+"    if (isPlainHostName(host)) {\n" \
+"        return (hostdom.search('/^' + host + '/') != -1);\n" \
+"    }\n" \
+"    else {\n" \
+"        return (host == hostdom);\n" \
+"    }\n" \
+"}\n" \
+"function shExpMatch(url, pattern) {\n" \
+"   pattern = pattern.replace(/\\./g, '\\\\.');\n" \
+"   pattern = pattern.replace(/\\*/g, '.*');\n" \
+"   pattern = pattern.replace(/\\?/g, '.');\n" \
+"   var newRe = new RegExp('^'+pattern+'$');\n" \
+"   return newRe.test(url);\n" \
+"}\n" \
+"var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
+"var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 
11};\n"\
+"function weekdayRange() {\n" \
+"    function getDay(weekday) {\n" \
+"        if (weekday in wdays) {\n" \
+"            return wdays[weekday];\n" \
+"        }\n" \
+"        return -1;\n" \
+"    }\n" \
+"    var date = new Date();\n" \
+"    var argc = arguments.length;\n" \
+"    var wday;\n" \
+"    if (argc < 1)\n" \
+"        return false;\n" \
+"    if (arguments[argc - 1] == 'GMT') {\n" \
+"        argc--;\n" \
+"        wday = date.getUTCDay();\n" \
+"    } else {\n" \
+"        wday = date.getDay();\n" \
+"    }\n" \
+"    var wd1 = getDay(arguments[0]);\n" \
+"    var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
+"    return (wd1 == -1 || wd2 == -1) ? false\n" \
+"                                    : (wd1 <= wday && wday <= wd2);\n" \
+"}\n" \
+"function dateRange() {\n" \
+"    function getMonth(name) {\n" \
+"        if (name in months) {\n" \
+"            return months[name];\n" \
+"        }\n" \
+"        return -1;\n" \
+"    }\n" \
+"    var date = new Date();\n" \
+"    var argc = arguments.length;\n" \
+"    if (argc < 1) {\n" \
+"        return false;\n" \
+"    }\n" \
+"    var isGMT = (arguments[argc - 1] == 'GMT');\n" \
+"    if (isGMT) {\n" \
+"        argc--;\n" \
+"    }\n" \
+"    if (argc == 1) {\n" \
+"        var tmp = parseInt(arguments[0]);\n" \
+"        if (isNaN(tmp)) {\n" \
+"            return ((isGMT ? date.getUTCMonth() : date.getMonth()) == getMonth(arguments[0]));\n" \
+"        } else if (tmp < 32) {\n" \
+"            return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" \
+"        } else {\n" \
+"            return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) == tmp);\n" \
+"        }\n" \
+"    }\n" \
+"    var year = date.getFullYear();\n" \
+"    var date1, date2;\n" \
+"    date1 = new Date(year, 0, 1, 0, 0, 0);\n" \
+"    date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
+"    var adjustMonth = false;\n" \
+"    for (var i = 0; i < (argc >> 1); i++) {\n" \
+"        var tmp = parseInt(arguments[i]);\n" \
+"        if (isNaN(tmp)) {\n" \
+"            var mon = getMonth(arguments[i]);\n" \
+"            date1.setMonth(mon);\n" \
+"        } else if (tmp < 32) {\n" \
+"            adjustMonth = (argc <= 2);\n" \
+"            date1.setDate(tmp);\n" \
+"        } else {\n" \
+"            date1.setFullYear(tmp);\n" \
+"        }\n" \
+"    }\n" \
+"    for (var i = (argc >> 1); i < argc; i++) {\n" \
+"        var tmp = parseInt(arguments[i]);\n" \
+"        if (isNaN(tmp)) {\n" \
+"            var mon = getMonth(arguments[i]);\n" \
+"            date2.setMonth(mon);\n" \
+"        } else if (tmp < 32) {\n" \
+"            date2.setDate(tmp);\n" \
+"        } else {\n" \
+"            date2.setFullYear(tmp);\n" \
+"        }\n" \
+"    }\n" \
+"    if (adjustMonth) {\n" \
+"        date1.setMonth(date.getMonth());\n" \
+"        date2.setMonth(date.getMonth());\n" \
+"    }\n" \
+"    if (isGMT) {\n" \
+"    var tmp = date;\n" \
+"        tmp.setFullYear(date.getUTCFullYear());\n" \
+"        tmp.setMonth(date.getUTCMonth());\n" \
+"        tmp.setDate(date.getUTCDate());\n" \
+"        tmp.setHours(date.getUTCHours());\n" \
+"        tmp.setMinutes(date.getUTCMinutes());\n" \
+"        tmp.setSeconds(date.getUTCSeconds());\n" \
+"        date = tmp;\n" \
+"    }\n" \
+"    return ((date1 <= date) && (date <= date2));\n" \
+"}\n" \
+"function timeRange() {\n" \
+"    var argc = arguments.length;\n" \
+"    var date = new Date();\n" \
+"    var isGMT= false;\n" \
+"    if (argc < 1) {\n" \
+"        return false;\n" \
+"    }\n" \
+"    if (arguments[argc - 1] == 'GMT') {\n" \
+"        isGMT = true;\n" \
+"        argc--;\n" \
+"    }\n" \
+"    var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
+"    var date1, date2;\n" \
+"    date1 = new Date();\n" \
+"    date2 = new Date();\n" \
+"    if (argc == 1) {\n" \
+"        return (hour == arguments[0]);\n" \
+"    } else if (argc == 2) {\n" \
+"        return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
+"    } else {\n" \
+"        switch (argc) {\n" \
+"        case 6:\n" \
+"            date1.setSeconds(arguments[2]);\n" \
+"            date2.setSeconds(arguments[5]);\n" \
+"        case 4:\n" \
+"            var middle = argc >> 1;\n" \
+"            date1.setHours(arguments[0]);\n" \
+"            date1.setMinutes(arguments[1]);\n" \
+"            date2.setHours(arguments[middle]);\n" \
+"            date2.setMinutes(arguments[middle + 1]);\n" \
+"            if (middle == 2) {\n" \
+"                date2.setSeconds(59);\n" \
+"            }\n" \
+"            break;\n" \
+"        default:\n" \
+"          throw 'timeRange: bad number of arguments'\n" \
+"        }\n" \
+"    }\n" \
+"    if (isGMT) {\n" \
+"        date.setFullYear(date.getUTCFullYear());\n" \
+"        date.setMonth(date.getUTCMonth());\n" \
+"        date.setDate(date.getUTCDate());\n" \
+"        date.setHours(date.getUTCHours());\n" \
+"        date.setMinutes(date.getUTCMinutes());\n" \
+"        date.setSeconds(date.getUTCSeconds());\n" \
+"    }\n" \
+"    return ((date1 <= date) && (date <= date2));\n" \
+"}\n" \
+""
diff --git a/tls/base/meson.build b/tls/base/meson.build
index f25cd351..79acfdc7 100644
--- a/tls/base/meson.build
+++ b/tls/base/meson.build
@@ -1,6 +1,5 @@
 tlsbase_sources = files(
   'gtlsconnection-base.c',
-  'gtlshttp.c',
   'gtlsinputstream.c',
   'gtlslog.c',
   'gtlsoutputstream.c',
@@ -13,4 +12,4 @@ tlsbase = static_library('tlsbase',
 
 tlsbase_dep = declare_dependency(link_with: tlsbase,
                                  include_directories: include_directories('.'),
-                                 dependencies: gio_dep)
+                                 dependencies: [gio_dep, util_dep])
diff --git a/tls/gnutls/gtlsdatabase-gnutls.c b/tls/gnutls/gtlsdatabase-gnutls.c
index eef1b168..37f35f06 100644
--- a/tls/gnutls/gtlsdatabase-gnutls.c
+++ b/tls/gnutls/gtlsdatabase-gnutls.c
@@ -34,7 +34,6 @@
 #include <gnutls/x509.h>
 
 #include "gtlscertificate-gnutls.h"
-#include "gtlshttp.h"
 #include "gtlsgnutls-version.h"
 
 typedef struct
diff --git a/tls/base/gtlshttp.c b/util/ghttp.c
similarity index 96%
rename from tls/base/gtlshttp.c
rename to util/ghttp.c
index 07334c6d..b2441ce8 100644
--- a/tls/base/gtlshttp.c
+++ b/util/ghttp.c
@@ -28,7 +28,7 @@
 #include <dlfcn.h>
 #endif
 
-#include "gtlshttp.h"
+#include "ghttp.h"
 
 typedef gpointer SoupSession;
 typedef gpointer SoupMessage;
@@ -107,7 +107,7 @@ init_libsoup (void)
 }
 
 /**
- * g_tls_request_uri:
+ * g_request_uri:
  * @uri: An HTTP URI to request
  * @cancellable: (nullable): A #GCancellable
  * @error: A #GError
@@ -119,9 +119,9 @@ init_libsoup (void)
  * Returns: A #GInputStream of the response body or %NULL on failure
  */
 GInputStream *
-g_tls_request_uri (const char    *uri,
-                   GCancellable  *cancellable,
-                   GError       **error)
+g_request_uri (const char    *uri,
+               GCancellable  *cancellable,
+               GError       **error)
 {
   GInputStream *istream = NULL;
 
diff --git a/tls/base/gtlshttp.h b/util/ghttp.h
similarity index 85%
rename from tls/base/gtlshttp.h
rename to util/ghttp.h
index 9e527ea5..b3c3b14e 100644
--- a/tls/base/gtlshttp.h
+++ b/util/ghttp.h
@@ -26,6 +26,6 @@
 
 #include <gio/gio.h>
 
-GInputStream *g_tls_request_uri (const char    *uri,
-                                 GCancellable  *cancellable,
-                                 GError       **error);
+GInputStream *g_request_uri (const char    *uri,
+                             GCancellable  *cancellable,
+                             GError       **error);
diff --git a/util/meson.build b/util/meson.build
new file mode 100644
index 00000000..754881da
--- /dev/null
+++ b/util/meson.build
@@ -0,0 +1,12 @@
+util_sources = files(
+  'ghttp.c'
+)
+
+util = static_library('util',
+                      util_sources,
+                      dependencies: [gio_dep, gmodule_dep],
+                      include_directories: top_inc)
+
+util_dep = declare_dependency(link_with: util,
+                              include_directories: include_directories('.'),
+                              dependencies: gio_dep)


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