4 * This library is free software you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, see <http://www.gnu.org/licenses/>.
19 * SECTION: e-source-proxy
20 * @include: libedataserver/libedataserver.h
21 * @short_description: #ESource extension for network proxy settings
23 * The #ESourceProxy extension defines a network proxy profile.
25 * An #ESource instance with this extension can serve as a #GProxyResolver.
27 * Access the extension as follows:
30 * #include <libedataserver/libedataserver.h>
32 * ESourceProxy *extension;
34 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_PROXY);
38 #include "e-source-proxy.h"
41 #include <glib/gi18n-lib.h>
43 #include <libedataserver/e-source-enumtypes.h>
44 #include <libedataserver/e-data-server-util.h>
46 #define E_SOURCE_PROXY_GET_PRIVATE(obj) \
47 (G_TYPE_INSTANCE_GET_PRIVATE \
48 ((obj), E_TYPE_SOURCE_PROXY, ESourceProxyPrivate))
50 typedef struct _AsyncContext AsyncContext;
52 struct _ESourceProxyPrivate {
56 gchar *autoconfig_url;
64 gboolean http_use_auth;
65 gchar *http_auth_user;
66 gchar *http_auth_password;
75 struct _AsyncContext {
85 PROP_HTTP_AUTH_PASSWORD,
101 E_TYPE_SOURCE_EXTENSION)
104 async_context_free (AsyncContext *async_context)
106 g_free (async_context->uri);
107 g_strfreev (async_context->proxies);
109 g_slice_free (AsyncContext, async_context);
113 source_proxy_direct (void)
117 proxies = g_new (gchar *, 2);
118 proxies[0] = g_strdup ("direct://");
125 source_proxy_dup_http_proxy (ESourceProxy *extension,
126 const gchar *http_host,
129 GString *http_proxy = g_string_new ("http://");
131 if (e_source_proxy_get_http_use_auth (extension)) {
134 gchar *enc_http_user;
135 gchar *enc_http_pass;
137 http_user = e_source_proxy_dup_http_auth_user (extension);
138 http_pass = e_source_proxy_dup_http_auth_password (extension);
140 enc_http_user = g_uri_escape_string (http_user, NULL, TRUE);
141 enc_http_pass = g_uri_escape_string (http_pass, NULL, TRUE);
143 g_string_append (http_proxy, enc_http_user);
144 g_string_append_c (http_proxy, ':');
145 g_string_append (http_proxy, enc_http_pass);
146 g_string_append_c (http_proxy, '@');
148 g_free (enc_http_user);
149 g_free (enc_http_pass);
155 g_string_append_printf (http_proxy, "%s:%u", http_host, http_port);
157 return g_string_free (http_proxy, FALSE);
161 source_proxy_lookup_pacrunner (ESource *source,
163 GCancellable *cancellable,
166 GDBusProxy *pacrunner;
167 ESourceProxy *extension;
168 const gchar *extension_name;
169 gchar *autoconfig_url;
170 gchar **proxies = NULL;
172 extension_name = E_SOURCE_EXTENSION_PROXY;
173 extension = e_source_get_extension (source, extension_name);
174 autoconfig_url = e_source_proxy_dup_autoconfig_url (extension);
176 if (autoconfig_url == NULL) {
177 proxies = source_proxy_direct ();
181 pacrunner = g_dbus_proxy_new_for_bus_sync (
183 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
184 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
186 "org.gtk.GLib.PACRunner",
187 "/org/gtk/GLib/PACRunner",
188 "org.gtk.GLib.PACRunner",
191 if (pacrunner != NULL) {
192 GVariant *variant_proxies;
194 variant_proxies = g_dbus_proxy_call_sync (
196 g_variant_new ("(ss)", autoconfig_url, uri),
197 G_DBUS_CALL_FLAGS_NONE, -1,
200 if (variant_proxies != NULL) {
201 g_variant_get (variant_proxies, "(^as)", &proxies);
202 g_variant_unref (variant_proxies);
205 g_object_unref (pacrunner);
209 g_free (autoconfig_url);
215 source_proxy_set_property (GObject *object,
220 switch (property_id) {
221 case PROP_AUTOCONFIG_URL:
222 e_source_proxy_set_autoconfig_url (
223 E_SOURCE_PROXY (object),
224 g_value_get_string (value));
228 e_source_proxy_set_ftp_host (
229 E_SOURCE_PROXY (object),
230 g_value_get_string (value));
234 e_source_proxy_set_ftp_port (
235 E_SOURCE_PROXY (object),
236 g_value_get_uint (value));
239 case PROP_HTTP_AUTH_PASSWORD:
240 e_source_proxy_set_http_auth_password (
241 E_SOURCE_PROXY (object),
242 g_value_get_string (value));
245 case PROP_HTTP_AUTH_USER:
246 e_source_proxy_set_http_auth_user (
247 E_SOURCE_PROXY (object),
248 g_value_get_string (value));
252 e_source_proxy_set_http_host (
253 E_SOURCE_PROXY (object),
254 g_value_get_string (value));
258 e_source_proxy_set_http_port (
259 E_SOURCE_PROXY (object),
260 g_value_get_uint (value));
263 case PROP_HTTP_USE_AUTH:
264 e_source_proxy_set_http_use_auth (
265 E_SOURCE_PROXY (object),
266 g_value_get_boolean (value));
269 case PROP_HTTPS_HOST:
270 e_source_proxy_set_https_host (
271 E_SOURCE_PROXY (object),
272 g_value_get_string (value));
275 case PROP_HTTPS_PORT:
276 e_source_proxy_set_https_port (
277 E_SOURCE_PROXY (object),
278 g_value_get_uint (value));
281 case PROP_IGNORE_HOSTS:
282 e_source_proxy_set_ignore_hosts (
283 E_SOURCE_PROXY (object),
284 g_value_get_boxed (value));
288 e_source_proxy_set_method (
289 E_SOURCE_PROXY (object),
290 g_value_get_enum (value));
293 case PROP_SOCKS_HOST:
294 e_source_proxy_set_socks_host (
295 E_SOURCE_PROXY (object),
296 g_value_get_string (value));
299 case PROP_SOCKS_PORT:
300 e_source_proxy_set_socks_port (
301 E_SOURCE_PROXY (object),
302 g_value_get_uint (value));
306 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
310 source_proxy_get_property (GObject *object,
315 switch (property_id) {
316 case PROP_AUTOCONFIG_URL:
317 g_value_take_string (
319 e_source_proxy_dup_autoconfig_url (
320 E_SOURCE_PROXY (object)));
324 g_value_take_string (
326 e_source_proxy_dup_ftp_host (
327 E_SOURCE_PROXY (object)));
333 e_source_proxy_get_ftp_port (
334 E_SOURCE_PROXY (object)));
337 case PROP_HTTP_AUTH_PASSWORD:
338 g_value_take_string (
340 e_source_proxy_dup_http_auth_password (
341 E_SOURCE_PROXY (object)));
344 case PROP_HTTP_AUTH_USER:
345 g_value_take_string (
347 e_source_proxy_dup_http_auth_user (
348 E_SOURCE_PROXY (object)));
352 g_value_take_string (
354 e_source_proxy_dup_http_host (
355 E_SOURCE_PROXY (object)));
361 e_source_proxy_get_http_port (
362 E_SOURCE_PROXY (object)));
365 case PROP_HTTP_USE_AUTH:
366 g_value_set_boolean (
368 e_source_proxy_get_http_use_auth (
369 E_SOURCE_PROXY (object)));
372 case PROP_HTTPS_HOST:
373 g_value_take_string (
375 e_source_proxy_dup_https_host (
376 E_SOURCE_PROXY (object)));
379 case PROP_HTTPS_PORT:
382 e_source_proxy_get_https_port (
383 E_SOURCE_PROXY (object)));
386 case PROP_IGNORE_HOSTS:
389 e_source_proxy_dup_ignore_hosts (
390 E_SOURCE_PROXY (object)));
396 e_source_proxy_get_method (
397 E_SOURCE_PROXY (object)));
400 case PROP_SOCKS_HOST:
401 g_value_take_string (
403 e_source_proxy_dup_socks_host (
404 E_SOURCE_PROXY (object)));
407 case PROP_SOCKS_PORT:
410 e_source_proxy_get_socks_port (
411 E_SOURCE_PROXY (object)));
415 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
419 source_proxy_finalize (GObject *object)
421 ESourceProxyPrivate *priv;
423 priv = E_SOURCE_PROXY_GET_PRIVATE (object);
425 g_mutex_clear (&priv->property_lock);
427 g_free (priv->autoconfig_url);
428 g_strfreev (priv->ignore_hosts);
429 g_free (priv->ftp_host);
430 g_free (priv->http_host);
431 g_free (priv->http_auth_user);
432 g_free (priv->http_auth_password);
433 g_free (priv->https_host);
434 g_free (priv->socks_host);
436 /* Chain up to parent's finalize() method. */
437 G_OBJECT_CLASS (e_source_proxy_parent_class)->finalize (object);
441 e_source_proxy_class_init (ESourceProxyClass *class)
443 GObjectClass *object_class;
444 ESourceExtensionClass *extension_class;
446 g_type_class_add_private (class, sizeof (ESourceProxyPrivate));
448 object_class = G_OBJECT_CLASS (class);
449 object_class->set_property = source_proxy_set_property;
450 object_class->get_property = source_proxy_get_property;
451 object_class->finalize = source_proxy_finalize;
453 extension_class = E_SOURCE_EXTENSION_CLASS (class);
454 extension_class->name = E_SOURCE_EXTENSION_PROXY;
456 g_object_class_install_property (
459 g_param_spec_string (
462 "Proxy autoconfiguration URL",
466 G_PARAM_STATIC_STRINGS |
467 E_SOURCE_PARAM_SETTING));
469 g_object_class_install_property (
472 g_param_spec_string (
475 "FTP proxy host name",
479 G_PARAM_STATIC_STRINGS |
480 E_SOURCE_PARAM_SETTING));
482 g_object_class_install_property (
492 G_PARAM_STATIC_STRINGS |
493 E_SOURCE_PARAM_SETTING));
495 g_object_class_install_property (
497 PROP_HTTP_AUTH_PASSWORD,
498 g_param_spec_string (
499 "http-auth-password",
500 "HTTP Auth Password",
501 "HTTP proxy password",
505 G_PARAM_STATIC_STRINGS |
506 E_SOURCE_PARAM_SETTING));
508 g_object_class_install_property (
511 g_param_spec_string (
514 "HTTP proxy username",
518 G_PARAM_STATIC_STRINGS |
519 E_SOURCE_PARAM_SETTING));
521 g_object_class_install_property (
524 g_param_spec_string (
527 "HTTP proxy host name",
531 G_PARAM_STATIC_STRINGS |
532 E_SOURCE_PARAM_SETTING));
534 g_object_class_install_property (
541 0, G_MAXUINT16, 8080,
544 G_PARAM_STATIC_STRINGS |
545 E_SOURCE_PARAM_SETTING));
547 g_object_class_install_property (
550 g_param_spec_boolean (
553 "Whether HTTP proxy server "
554 "connections require authentication",
558 G_PARAM_STATIC_STRINGS |
559 E_SOURCE_PARAM_SETTING));
561 g_object_class_install_property (
564 g_param_spec_string (
567 "Secure HTTP proxy host name",
571 G_PARAM_STATIC_STRINGS |
572 E_SOURCE_PARAM_SETTING));
574 g_object_class_install_property (
580 "Secure HTTP proxy port",
584 G_PARAM_STATIC_STRINGS |
585 E_SOURCE_PARAM_SETTING));
587 g_object_class_install_property (
593 "Hosts to connect directly",
597 G_PARAM_STATIC_STRINGS |
598 E_SOURCE_PARAM_SETTING));
600 g_object_class_install_property (
606 "Proxy configuration method",
608 E_PROXY_METHOD_DEFAULT,
611 G_PARAM_STATIC_STRINGS |
612 E_SOURCE_PARAM_SETTING));
614 g_object_class_install_property (
617 g_param_spec_string (
620 "SOCKS proxy host name",
624 G_PARAM_STATIC_STRINGS |
625 E_SOURCE_PARAM_SETTING));
627 g_object_class_install_property (
637 G_PARAM_STATIC_STRINGS |
638 E_SOURCE_PARAM_SETTING));
642 e_source_proxy_init (ESourceProxy *extension)
644 extension->priv = E_SOURCE_PROXY_GET_PRIVATE (extension);
645 g_mutex_init (&extension->priv->property_lock);
649 * e_source_proxy_get_method:
650 * @extension: an #ESourceProxy
652 * Returns the proxy configuration method for @extension.
654 * The proxy configuration method determines the behavior of
655 * e_source_proxy_lookup().
657 * Returns: the proxy configuration method
662 e_source_proxy_get_method (ESourceProxy *extension)
664 g_return_val_if_fail (
665 E_IS_SOURCE_PROXY (extension),
666 E_PROXY_METHOD_DEFAULT);
668 return extension->priv->method;
672 * e_source_proxy_set_method:
673 * @extension: an #ESourceProxy
674 * @method: the proxy configuration method
676 * Sets the proxy configuration method for @extension.
678 * The proxy configuration method determines the behavior of
679 * e_source_proxy_lookup().
684 e_source_proxy_set_method (ESourceProxy *extension,
687 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
689 if (method == extension->priv->method)
692 extension->priv->method = method;
694 g_object_notify (G_OBJECT (extension), "method");
698 * e_source_proxy_get_autoconfig_url:
699 * @extension: an #ESourceProxy
701 * Returns the URL that provides proxy configuration values. When the
702 * @extension's #ESourceProxy:method is @E_PROXY_METHOD_AUTO, this URL
703 * is used to look up proxy information for all protocols.
705 * Returns: the autoconfiguration URL
710 e_source_proxy_get_autoconfig_url (ESourceProxy *extension)
712 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
714 return extension->priv->autoconfig_url;
718 * e_source_proxy_dup_autoconfig_url:
719 * @extension: an #ESourceProxy
721 * Thread-safe variation of e_source_proxy_get_autoconfig_url().
722 * Use this function when accessing @extension from multiple threads.
724 * The returned string should be freed with g_free() when no longer needed.
726 * Returns: a newly-allocated copy of #ESourceProxy:autoconfig-url
731 e_source_proxy_dup_autoconfig_url (ESourceProxy *extension)
733 const gchar *protected;
736 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
738 g_mutex_lock (&extension->priv->property_lock);
740 protected = e_source_proxy_get_autoconfig_url (extension);
741 duplicate = g_strdup (protected);
743 g_mutex_unlock (&extension->priv->property_lock);
749 * e_source_proxy_set_autoconfig_url:
750 * @extension: an #ESourceProxy
751 * @autoconfig_url: an autoconfiguration URL
753 * Sets the URL that provides proxy configuration values. When the
754 * @extension's #ESourceProxy:method is @E_PROXY_METHOD_AUTO, this URL
755 * is used to look up proxy information for all protocols.
760 e_source_proxy_set_autoconfig_url (ESourceProxy *extension,
761 const gchar *autoconfig_url)
763 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
765 g_mutex_lock (&extension->priv->property_lock);
767 if (g_strcmp0 (autoconfig_url, extension->priv->autoconfig_url) == 0) {
768 g_mutex_unlock (&extension->priv->property_lock);
772 g_free (extension->priv->autoconfig_url);
773 extension->priv->autoconfig_url = e_util_strdup_strip (autoconfig_url);
775 g_mutex_unlock (&extension->priv->property_lock);
777 g_object_notify (G_OBJECT (extension), "autoconfig-url");
781 * e_source_proxy_get_ignore_hosts:
782 * @extension: an #ESourceProxy
784 * Returns a %NULL-terminated string array of hosts which are connected to
785 * directly, rather than via the proxy (if it is active). The array elements
786 * can be hostnames, domains (using an initial wildcard like *.foo.com), IP
787 * host addresses (both IPv4 and IPv6) and network addresses with a netmask
788 * (something like 192.168.0.0/24).
790 * The returned array is owned by @extension and should not be modified or
793 * Returns: (transfer none): a %NULL-terminated string array of hosts
797 const gchar * const *
798 e_source_proxy_get_ignore_hosts (ESourceProxy *extension)
800 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
802 return (const gchar * const *) extension->priv->ignore_hosts;
806 * e_source_proxy_dup_ignore_hosts:
807 * @extension: an #ESourceProxy
809 * Thread-safe variation of e_source_proxy_get_ignore_hosts().
810 * Use this function when accessing @extension from multiple threads.
812 * The returned string array should be freed with g_strfreev() when no
815 * Returns: (transfer full): a newly-allocated copy of
816 * #ESourceProxy:ignore-hosts
821 e_source_proxy_dup_ignore_hosts (ESourceProxy *extension)
823 const gchar * const *protected;
826 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
828 g_mutex_lock (&extension->priv->property_lock);
830 protected = e_source_proxy_get_ignore_hosts (extension);
831 duplicate = g_strdupv ((gchar **) protected);
833 g_mutex_unlock (&extension->priv->property_lock);
839 * e_source_proxy_set_ignore_hosts:
840 * @extension: an #ESourceProxy
841 * @ignore_hosts: a %NULL-terminated string array of hosts
843 * Sets the hosts which are connected to directly, rather than via the proxy
844 * (if it is active). The array elements can be hostnames, domains (using an
845 * initial wildcard like *.foo.com), IP host addresses (both IPv4 and IPv6)
846 * and network addresses with a netmask (something like 192.168.0.0/24).
851 e_source_proxy_set_ignore_hosts (ESourceProxy *extension,
852 const gchar * const *ignore_hosts)
854 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
856 g_mutex_lock (&extension->priv->property_lock);
858 if (e_util_strv_equal (ignore_hosts, extension->priv->ignore_hosts)) {
859 g_mutex_unlock (&extension->priv->property_lock);
863 g_strfreev (extension->priv->ignore_hosts);
864 extension->priv->ignore_hosts = g_strdupv ((gchar **) ignore_hosts);
866 /* Strip leading and trailing whitespace from each element. */
867 if (extension->priv->ignore_hosts != NULL) {
870 length = g_strv_length (extension->priv->ignore_hosts);
871 for (ii = 0; ii < length; ii++)
872 g_strstrip (extension->priv->ignore_hosts[ii]);
875 g_mutex_unlock (&extension->priv->property_lock);
877 g_object_notify (G_OBJECT (extension), "ignore-hosts");
881 * e_source_proxy_get_ftp_host:
882 * @extension: an #ESourceProxy
884 * Returns the machine name to proxy FTP through when @extension's
885 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
887 * Returns: FTP proxy host name
892 e_source_proxy_get_ftp_host (ESourceProxy *extension)
894 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
896 return extension->priv->ftp_host;
900 * e_source_proxy_dup_ftp_host:
901 * @extension: an #ESourceProxy
903 * Thread-safe variation of e_source_proxy_get_ftp_host().
904 * Use this function when accessing @extension from multiple threads.
906 * The returned string should be freed with g_free() when no longer needed.
908 * Returns: a newly-allocated copy of #ESourceProxy:ftp-host
913 e_source_proxy_dup_ftp_host (ESourceProxy *extension)
915 const gchar *protected;
918 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
920 g_mutex_lock (&extension->priv->property_lock);
922 protected = e_source_proxy_get_ftp_host (extension);
923 duplicate = g_strdup (protected);
925 g_mutex_unlock (&extension->priv->property_lock);
931 * e_source_proxy_set_ftp_host:
932 * @extension: an #ESourceProxy
933 * @ftp_host: FTP proxy host name
935 * Sets the machine name to proxy FTP through when @extension's
936 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
941 e_source_proxy_set_ftp_host (ESourceProxy *extension,
942 const gchar *ftp_host)
944 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
946 g_mutex_lock (&extension->priv->property_lock);
948 if (g_strcmp0 (ftp_host, extension->priv->ftp_host) == 0) {
949 g_mutex_unlock (&extension->priv->property_lock);
953 g_free (extension->priv->ftp_host);
954 extension->priv->ftp_host = e_util_strdup_strip (ftp_host);
956 g_mutex_unlock (&extension->priv->property_lock);
958 g_object_notify (G_OBJECT (extension), "ftp-host");
962 * e_source_proxy_get_ftp_port:
963 * @extension: an #ESourceProxy
965 * Returns the port on the machine defined by #ESourceProxy:ftp-host to proxy
966 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
968 * Returns: FTP proxy port
973 e_source_proxy_get_ftp_port (ESourceProxy *extension)
975 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
977 return extension->priv->ftp_port;
981 * e_source_proxy_set_ftp_port:
982 * @extension: an #ESourceProxy
983 * @ftp_port: FTP proxy port
985 * Sets the port on the machine defined by #ESourceProxy:ftp-host to proxy
986 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
991 e_source_proxy_set_ftp_port (ESourceProxy *extension,
994 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
996 if (ftp_port == extension->priv->ftp_port)
999 extension->priv->ftp_port = ftp_port;
1001 g_object_notify (G_OBJECT (extension), "ftp-port");
1005 * e_source_proxy_get_http_host:
1006 * @extension: an #ESourceProxy
1008 * Returns the machine name to proxy HTTP through when @extension's
1009 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1011 * Returns: HTTP proxy host name
1016 e_source_proxy_get_http_host (ESourceProxy *extension)
1018 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1020 return extension->priv->http_host;
1024 * e_source_proxy_dup_http_host:
1025 * @extension: an #ESourceProxy
1027 * Thread-safe variation of e_source_proxy_get_http_host().
1028 * Use this function when accessing @extension from multiple threads.
1030 * The returned string should be freed with g_free() when no longer needed.
1032 * Returns: a newly-allocated copy of #ESourceProxy:http-host
1037 e_source_proxy_dup_http_host (ESourceProxy *extension)
1039 const gchar *protected;
1042 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1044 g_mutex_lock (&extension->priv->property_lock);
1046 protected = e_source_proxy_get_http_host (extension);
1047 duplicate = g_strdup (protected);
1049 g_mutex_unlock (&extension->priv->property_lock);
1055 * e_source_proxy_set_http_host:
1056 * @extension: an #ESourceProxy
1057 * @http_host: HTTP proxy host name
1059 * Sets the machine name to proxy HTTP through when @extension's
1060 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1065 e_source_proxy_set_http_host (ESourceProxy *extension,
1066 const gchar *http_host)
1068 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1070 g_mutex_lock (&extension->priv->property_lock);
1072 if (g_strcmp0 (http_host, extension->priv->http_host) == 0) {
1073 g_mutex_unlock (&extension->priv->property_lock);
1077 g_free (extension->priv->http_host);
1078 extension->priv->http_host = e_util_strdup_strip (http_host);
1080 g_mutex_unlock (&extension->priv->property_lock);
1082 g_object_notify (G_OBJECT (extension), "http-host");
1086 * e_source_proxy_get_http_port:
1087 * @extension: an #ESourceProxy
1089 * Returns the port on the machine defined by #ESourceProxy:http-host to proxy
1090 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1092 * Returns: HTTP proxy port
1097 e_source_proxy_get_http_port (ESourceProxy *extension)
1099 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1101 return extension->priv->http_port;
1105 * e_source_proxy_set_http_port:
1106 * @extension: an #ESourceProxy
1107 * @http_port: HTTP proxy port
1109 * Sets the port on the machine defined by #ESourceProxy:http-host to proxy
1110 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1115 e_source_proxy_set_http_port (ESourceProxy *extension,
1118 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1120 if (http_port == extension->priv->http_port)
1123 extension->priv->http_port = http_port;
1125 g_object_notify (G_OBJECT (extension), "http-port");
1129 * e_source_proxy_get_http_use_auth:
1130 * @extension: an #ESourceProxy
1132 * Returns whether the HTTP proxy server at #ESourceProxy:http-host and
1133 * #ESourceProxy:http-port requires authentication.
1135 * The username/password combo is defined by #ESourceProxy:http-auth-user
1136 * and #ESourceProxy:http-auth-password, but only applies when @extension's
1137 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1139 * Returns: whether to authenticate HTTP proxy connections
1144 e_source_proxy_get_http_use_auth (ESourceProxy *extension)
1146 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), FALSE);
1148 return extension->priv->http_use_auth;
1152 * e_source_proxy_set_http_use_auth:
1153 * @extension: an #ESourceProxy
1154 * @http_use_auth: whether to authenticate HTTP proxy connections
1156 * Sets whether the HTTP proxy server at #ESourceProxy:http-host and
1157 * #ESourceProxy:http-port requires authentication.
1159 * The username/password combo is defined by #ESourceProxy:http-auth-user
1160 * and #ESourceProxy:http-auth-password, but only applies when @extension's
1161 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1166 e_source_proxy_set_http_use_auth (ESourceProxy *extension,
1167 gboolean http_use_auth)
1169 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1171 if (http_use_auth == extension->priv->http_use_auth)
1174 extension->priv->http_use_auth = http_use_auth;
1176 g_object_notify (G_OBJECT (extension), "http-use-auth");
1180 * e_source_proxy_get_http_auth_user:
1181 * @extension: an #ESourceProxy
1183 * Returns the user name to pass as authentication when doing HTTP proxying
1184 * and #ESourceProxy:http-use-auth is %TRUE.
1186 * Returns: HTTP proxy username
1191 e_source_proxy_get_http_auth_user (ESourceProxy *extension)
1193 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1195 return extension->priv->http_auth_user;
1199 * e_source_proxy_dup_http_auth_user:
1200 * @extension: an #ESourceProxy
1202 * Thread-safe variation of e_source_proxy_get_http_auth_user().
1203 * Use this function when accessing @extension from multiple threads.
1205 * The returned string should be freed with g_free() when no longer needed.
1207 * Returns: a newly-allocated copy of #ESourceProxy:http-auth-user
1212 e_source_proxy_dup_http_auth_user (ESourceProxy *extension)
1214 const gchar *protected;
1217 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1219 g_mutex_lock (&extension->priv->property_lock);
1221 protected = e_source_proxy_get_http_auth_user (extension);
1222 duplicate = g_strdup (protected);
1224 g_mutex_unlock (&extension->priv->property_lock);
1230 * e_source_proxy_set_http_auth_user:
1231 * @extension: an #ESourceProxy
1232 * @http_auth_user: HTTP proxy username
1234 * Sets the user name to pass as authentication when doing HTTP proxying
1235 * and #ESourceProxy:http-use-auth is %TRUE.
1240 e_source_proxy_set_http_auth_user (ESourceProxy *extension,
1241 const gchar *http_auth_user)
1243 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1245 g_mutex_lock (&extension->priv->property_lock);
1247 if (g_strcmp0 (http_auth_user, extension->priv->http_auth_user) == 0) {
1248 g_mutex_unlock (&extension->priv->property_lock);
1252 g_free (extension->priv->http_auth_user);
1253 extension->priv->http_auth_user = e_util_strdup_strip (http_auth_user);
1255 g_mutex_unlock (&extension->priv->property_lock);
1257 g_object_notify (G_OBJECT (extension), "http-auth-user");
1261 * e_source_proxy_get_http_auth_password:
1262 * @extension: an #ESourceProxy
1264 * Returns the password to pass as authentication when doing HTTP proxying
1265 * and #ESourceProxy:http-use-auth is %TRUE.
1267 * Returns: HTTP proxy password
1272 e_source_proxy_get_http_auth_password (ESourceProxy *extension)
1274 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1276 return extension->priv->http_auth_password;
1280 * e_source_proxy_dup_http_auth_password:
1281 * @extension: an #ESourceProxy
1283 * Thread-safe variation of e_source_proxy_get_http_auth_password().
1284 * Use this function when accessing @extension from multiple threads.
1286 * The returned string should be freed with g_free() when no longer needed.
1288 * Returns: a newly-allocated copy of #ESourceProxy:http-auth-password
1293 e_source_proxy_dup_http_auth_password (ESourceProxy *extension)
1295 const gchar *protected;
1298 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1300 g_mutex_lock (&extension->priv->property_lock);
1302 protected = e_source_proxy_get_http_auth_password (extension);
1303 duplicate = g_strdup (protected);
1305 g_mutex_unlock (&extension->priv->property_lock);
1311 * e_source_proxy_set_http_auth_password:
1312 * @extension: an #ESourceProxy
1313 * @http_auth_password: HTTP proxy password
1315 * Sets the password to pass as authentication when doing HTTP proxying
1316 * and #ESourceProxy:http-use-auth is %TRUE.
1321 e_source_proxy_set_http_auth_password (ESourceProxy *extension,
1322 const gchar *http_auth_password)
1324 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1326 g_mutex_lock (&extension->priv->property_lock);
1328 if (g_strcmp0 (http_auth_password, extension->priv->http_auth_password) == 0) {
1329 g_mutex_unlock (&extension->priv->property_lock);
1333 g_free (extension->priv->http_auth_password);
1334 extension->priv->http_auth_password = e_util_strdup_strip (http_auth_password);
1336 g_mutex_unlock (&extension->priv->property_lock);
1338 g_object_notify (G_OBJECT (extension), "http-auth-password");
1342 * e_source_proxy_get_https_host:
1343 * @extension: an #ESourceProxy
1345 * Returns the machine name to proxy secure HTTP through when @extension's
1346 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1348 * Returns: secure HTTP proxy host name
1353 e_source_proxy_get_https_host (ESourceProxy *extension)
1355 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1357 return extension->priv->https_host;
1361 * e_source_proxy_dup_https_host:
1362 * @extension: an #ESourceProxy
1364 * Threads-safe variation of e_source_proxy_get_https_host().
1365 * Use this function when accessing @extension from multiple threads.
1367 * The returned string should be freed with g_free() when no longer needed.
1369 * Returns: a newly-allocated copy of #ESourceProxy:https-host
1374 e_source_proxy_dup_https_host (ESourceProxy *extension)
1376 const gchar *protected;
1379 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1381 g_mutex_lock (&extension->priv->property_lock);
1383 protected = e_source_proxy_get_https_host (extension);
1384 duplicate = g_strdup (protected);
1386 g_mutex_unlock (&extension->priv->property_lock);
1392 * e_source_proxy_set_https_host:
1393 * @extension: an #ESourceProxy
1394 * @https_host: secure HTTP proxy host name
1396 * Sets the machine name to proxy secure HTTP through when @extension's
1397 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1402 e_source_proxy_set_https_host (ESourceProxy *extension,
1403 const gchar *https_host)
1405 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1407 g_mutex_lock (&extension->priv->property_lock);
1409 if (g_strcmp0 (https_host, extension->priv->https_host) == 0) {
1410 g_mutex_unlock (&extension->priv->property_lock);
1414 g_free (extension->priv->https_host);
1415 extension->priv->https_host = e_util_strdup_strip (https_host);
1417 g_mutex_unlock (&extension->priv->property_lock);
1419 g_object_notify (G_OBJECT (extension), "https-host");
1423 * e_source_proxy_get_https_port:
1424 * @extension: an #ESourceProxy
1426 * Returns the port on the machine defined by #ESourceProxy:https-host to proxy
1427 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1429 * Returns: secure HTTP proxy port
1434 e_source_proxy_get_https_port (ESourceProxy *extension)
1436 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1438 return extension->priv->https_port;
1442 * e_source_proxy_set_https_port:
1443 * @extension: an #ESourceProxy
1444 * @https_port: secure HTTP proxy port
1446 * Sets the port on the machine defined by #ESourceProxy:https-host to proxy
1447 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1452 e_source_proxy_set_https_port (ESourceProxy *extension,
1455 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1457 if (https_port == extension->priv->https_port)
1460 extension->priv->https_port = https_port;
1462 g_object_notify (G_OBJECT (extension), "https-port");
1466 * e_source_proxy_get_socks_host:
1467 * @extension: an #ESourceProxy
1469 * Returns the machine name to use as a SOCKS proxy when @extension's
1470 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1472 * Returns: SOCKS proxy host name
1477 e_source_proxy_get_socks_host (ESourceProxy *extension)
1479 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1481 return extension->priv->socks_host;
1485 * e_source_proxy_dup_socks_host:
1486 * @extension: an #ESourceProxy
1488 * Thread-safe variation of e_source-proxy_get_socks_host().
1489 * Use this function when accessing @extension from multiple threads.
1491 * The returned string should be freed with g_free() when no longer needed.
1493 * Returns: a newly-allocated copy of #ESourceProxy:socks-host
1498 e_source_proxy_dup_socks_host (ESourceProxy *extension)
1500 const gchar *protected;
1503 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1505 g_mutex_lock (&extension->priv->property_lock);
1507 protected = e_source_proxy_get_socks_host (extension);
1508 duplicate = g_strdup (protected);
1510 g_mutex_unlock (&extension->priv->property_lock);
1516 * e_source_proxy_set_socks_host:
1517 * @extension: an #ESourceProxy
1518 * @socks_host: SOCKS proxy host name
1520 * Sets the machine name to use as a SOCKS proxy when @extension's
1521 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1526 e_source_proxy_set_socks_host (ESourceProxy *extension,
1527 const gchar *socks_host)
1529 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1531 g_mutex_lock (&extension->priv->property_lock);
1533 if (g_strcmp0 (socks_host, extension->priv->socks_host) == 0) {
1534 g_mutex_unlock (&extension->priv->property_lock);
1538 g_free (extension->priv->socks_host);
1539 extension->priv->socks_host = e_util_strdup_strip (socks_host);
1541 g_mutex_unlock (&extension->priv->property_lock);
1543 g_object_notify (G_OBJECT (extension), "socks-host");
1547 * e_source_proxy_get_socks_port:
1548 * @extension: an #ESourceProxy
1550 * Returns the port on the machine defined by #ESourceProxy:socks-host to proxy
1551 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1553 * Returns: SOCKS proxy port
1558 e_source_proxy_get_socks_port (ESourceProxy *extension)
1560 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1562 return extension->priv->socks_port;
1566 * e_source_proxy_set_socks_port:
1567 * @extension: an #ESourceProxy
1568 * @socks_port: SOCKS proxy port
1570 * Sets the port on the machine defined by #ESourceProxy:socks-host to proxy
1571 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1576 e_source_proxy_set_socks_port (ESourceProxy *extension,
1579 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1581 if (socks_port == extension->priv->socks_port)
1584 extension->priv->socks_port = socks_port;
1586 g_object_notify (G_OBJECT (extension), "socks-port");
1590 * e_source_proxy_lookup_sync:
1591 * @source: an #ESource
1592 * @uri: a URI representing the destination to connect to
1593 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1594 * @error: return location for a #GError, or %NULL
1596 * Looks into @source's #ESourceProxy extension to determine what proxy,
1597 * if any, to use to connect to @uri. The returned proxy URIs are of the
1598 * same form described by g_proxy_resolver_lookup().
1600 * The proxy extension's #ESourceProxy:method controls how proxy URIs are
1603 * When using @E_PROXY_METHOD_DEFAULT, the function will defer to the
1604 * #GProxyResolver returned by g_proxy_resolver_get_default().
1606 * When using @E_PROXY_METHOD_MANUAL, the function will configure a
1607 * #GSimpleProxyResolver from the HTTP, HTTPS, FTP and SOCKS properties,
1608 * as well as #ESourceProxy:ignore-hosts.
1610 * When using @E_PROXY_METHOD_AUTO, the function will execute a proxy
1611 * auto-config (PAC) file at #ESourceProxy:autoconfig-url.
1613 * When using @E_PROXY_METHOD_NONE, the function will only return
1614 * <literal>direct://</literal>.
1616 * If @source does not have an #ESourceProxy extension, the function sets
1617 * @error to @G_IO_ERROR_NOT_SUPPORTED and returns %NULL.
1619 * Free the returned proxy URIs with g_strfreev() when finished with them.
1621 * Returns: a %NULL-terminated array of proxy URIs, or %NULL
1626 e_source_proxy_lookup_sync (ESource *source,
1628 GCancellable *cancellable,
1631 GProxyResolver *resolver = NULL;
1632 ESourceProxy *extension;
1633 EProxyMethod method;
1634 const gchar *extension_name;
1637 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1638 g_return_val_if_fail (uri != NULL, NULL);
1640 extension_name = E_SOURCE_EXTENSION_PROXY;
1642 if (!e_source_has_extension (source, extension_name)) {
1645 G_IO_ERROR_NOT_SUPPORTED,
1646 _("Source '%s' does not support proxy lookups"),
1647 e_source_get_display_name (source));
1651 extension = e_source_get_extension (source, extension_name);
1652 method = e_source_proxy_get_method (extension);
1654 if (method == E_PROXY_METHOD_DEFAULT) {
1655 resolver = g_proxy_resolver_get_default ();
1656 if (resolver != NULL)
1657 g_object_ref (resolver);
1660 if (method == E_PROXY_METHOD_MANUAL) {
1661 gchar *ftp_proxy = NULL;
1662 gchar *http_proxy = NULL;
1663 gchar *https_proxy = NULL;
1664 gchar *socks_proxy = NULL;
1665 gchar **ignore_hosts;
1669 host = e_source_proxy_dup_ftp_host (extension);
1670 port = e_source_proxy_get_ftp_port (extension);
1671 if (host != NULL && port > 0) {
1672 ftp_proxy = g_strdup_printf (
1673 "ftp://%s:%u", host, port);
1677 host = e_source_proxy_dup_http_host (extension);
1678 port = e_source_proxy_get_http_port (extension);
1679 if (host != NULL && port > 0) {
1680 /* This one is a little more complicated. */
1681 http_proxy = source_proxy_dup_http_proxy (
1682 extension, host, port);
1686 host = e_source_proxy_dup_https_host (extension);
1687 port = e_source_proxy_get_https_port (extension);
1688 if (host != NULL && port > 0) {
1689 https_proxy = g_strdup_printf (
1690 "http://%s:%u", host, port);
1694 host = e_source_proxy_dup_socks_host (extension);
1695 port = e_source_proxy_get_socks_port (extension);
1696 if (host != NULL && port > 0) {
1697 socks_proxy = g_strdup_printf (
1698 "socks://%s:%u", host, port);
1702 ignore_hosts = e_source_proxy_dup_ignore_hosts (extension);
1703 resolver = g_simple_proxy_resolver_new (NULL, ignore_hosts);
1704 g_strfreev (ignore_hosts);
1706 if (ftp_proxy != NULL) {
1707 g_simple_proxy_resolver_set_uri_proxy (
1708 G_SIMPLE_PROXY_RESOLVER (resolver),
1713 if (https_proxy != NULL) {
1714 g_simple_proxy_resolver_set_uri_proxy (
1715 G_SIMPLE_PROXY_RESOLVER (resolver),
1716 "https", https_proxy);
1717 g_free (https_proxy);
1718 } else if (http_proxy != NULL) {
1719 g_simple_proxy_resolver_set_uri_proxy (
1720 G_SIMPLE_PROXY_RESOLVER (resolver),
1721 "https", http_proxy);
1724 if (http_proxy != NULL) {
1725 g_simple_proxy_resolver_set_uri_proxy (
1726 G_SIMPLE_PROXY_RESOLVER (resolver),
1727 "http", http_proxy);
1728 g_free (http_proxy);
1731 if (socks_proxy != NULL) {
1732 g_simple_proxy_resolver_set_uri_proxy (
1733 G_SIMPLE_PROXY_RESOLVER (resolver),
1734 "socks", socks_proxy);
1735 g_simple_proxy_resolver_set_default_proxy (
1736 G_SIMPLE_PROXY_RESOLVER (resolver),
1738 g_free (socks_proxy);
1742 if (method == E_PROXY_METHOD_AUTO) {
1743 proxies = source_proxy_lookup_pacrunner (
1744 source, uri, cancellable, error);
1746 } else if (resolver != NULL) {
1747 proxies = g_proxy_resolver_lookup (
1748 resolver, uri, cancellable, error);
1751 proxies = source_proxy_direct ();
1754 g_clear_object (&resolver);
1759 /* Helper for e_source_proxy_lookup() */
1761 source_proxy_lookup_thread (GSimpleAsyncResult *simple,
1763 GCancellable *cancellable)
1765 AsyncContext *async_context;
1766 GError *local_error = NULL;
1768 async_context = g_simple_async_result_get_op_res_gpointer (simple);
1770 async_context->proxies = e_source_proxy_lookup_sync (
1773 cancellable, &local_error);
1775 if (local_error != NULL)
1776 g_simple_async_result_take_error (simple, local_error);
1780 * e_source_proxy_lookup:
1781 * @source: an #ESource
1782 * @uri: a URI representing the destination to connect to
1783 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1784 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
1786 * @user_data: (closure): data to pass to the callback function
1788 * Asynchronously determines what proxy, if any, to use to connect to @uri.
1789 * See e_source_proxy_lookup_sync() for more details.
1791 * When the operation is finished, @callback will be called. You can then
1792 * call e_source_proxy_lookup_finish() to get the result of the operation.
1797 e_source_proxy_lookup (ESource *source,
1799 GCancellable *cancellable,
1800 GAsyncReadyCallback callback,
1803 GSimpleAsyncResult *simple;
1804 AsyncContext *async_context;
1806 g_return_if_fail (E_IS_SOURCE (source));
1807 g_return_if_fail (uri != NULL);
1809 async_context = g_slice_new0 (AsyncContext);
1810 async_context->uri = g_strdup (uri);
1812 simple = g_simple_async_result_new (
1813 G_OBJECT (source), callback,
1814 user_data, e_source_proxy_lookup);
1816 g_simple_async_result_set_check_cancellable (simple, cancellable);
1818 g_simple_async_result_set_op_res_gpointer (
1819 simple, async_context, (GDestroyNotify) async_context_free);
1821 g_simple_async_result_run_in_thread (
1822 simple, source_proxy_lookup_thread,
1823 G_PRIORITY_DEFAULT, cancellable);
1825 g_object_unref (simple);
1829 * e_source_proxy_lookup_finish:
1830 * @source: an #ESource
1831 * @result: a #GAsyncResult
1832 * @error: return location for a #GError, or %NULL
1834 * Finishes the operation started with e_source_proxy_lookup().
1836 * Free the returned proxy URIs with g_strfreev() when finished with them.
1838 * Returns: a %NULL-terminated array of proxy URIs, or %NULL
1843 e_source_proxy_lookup_finish (ESource *source,
1844 GAsyncResult *result,
1847 GSimpleAsyncResult *simple;
1848 AsyncContext *async_context;
1851 g_return_val_if_fail (
1852 g_simple_async_result_is_valid (
1853 result, G_OBJECT (source), e_source_proxy_lookup), NULL);
1855 simple = G_SIMPLE_ASYNC_RESULT (result);
1856 async_context = g_simple_async_result_get_op_res_gpointer (simple);
1858 if (g_simple_async_result_propagate_error (simple, error))
1861 g_return_val_if_fail (async_context->proxies != NULL, NULL);
1863 proxies = async_context->proxies;
1864 async_context->proxies = NULL;