2 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
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 Lesser 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/>.
16 * Authors: Jeffrey Stedfast <fejj@ximian.com>
17 * Veerapuram Varadhan <vvaradhan@novell.com>
20 #include "evolution-data-server-config.h"
28 #ifndef IN6_ARE_ADDR_EQUAL
29 #define IN6_ARE_ADDR_EQUAL(a, b) \
30 (memcmp ((gpointer)(a), (gpointer)(b), sizeof (struct in6_addr)) == 0)
33 #include <netinet/in.h>
34 #include <sys/socket.h>
37 #include <libsoup/soup-address.h>
38 #include <libsoup/soup-uri.h>
41 #define E_PROXY_GET_PRIVATE(obj) \
42 (G_TYPE_INSTANCE_GET_PRIVATE \
43 ((obj), E_TYPE_PROXY, EProxyPrivate))
45 G_DEFINE_TYPE (EProxy
, e_proxy
, G_TYPE_OBJECT
)
51 PROXY_TYPE_SYSTEM
= 0,
54 PROXY_TYPE_AUTO_URL
/* no auto-proxy at the moment */
59 E_PROXY_KEY_USE_HTTP_PROXY
,
60 E_PROXY_KEY_HTTP_HOST
,
61 E_PROXY_KEY_HTTP_PORT
,
62 E_PROXY_KEY_HTTP_USE_AUTH
,
63 E_PROXY_KEY_HTTP_AUTH_USER
,
64 E_PROXY_KEY_HTTP_AUTH_PWD
,
65 E_PROXY_KEY_HTTP_IGNORE_HOSTS
,
66 E_PROXY_KEY_HTTPS_HOST
,
67 E_PROXY_KEY_HTTPS_PORT
,
68 E_PROXY_KEY_SOCKS_HOST
,
69 E_PROXY_KEY_SOCKS_PORT
,
70 E_PROXY_KEY_AUTOCONFIG_URL
73 struct _EProxyPrivate
{
74 SoupURI
*uri_http
, *uri_https
, *uri_socks
;
75 GSList
* ign_hosts
; /* List of hostnames. (Strings) */
76 GSList
* ign_addrs
; /* List of hostaddrs. (ProxyHostAddrs) */
77 gboolean use_proxy
; /* Is our-proxy enabled? */
79 GSettings
*evolution_proxy_settings
;
80 GSettings
*proxy_settings
;
81 GSettings
*proxy_http_settings
;
82 GSettings
*proxy_https_settings
;
83 GSettings
*proxy_socks_settings
;
86 /* Enum definition is copied from gnome-vfs/modules/http-proxy.c */
93 ProxyAddrType type
; /* Specifies whether IPV4 or IPV6 */
94 gpointer addr
; /* Either in_addr * or in6_addr * */
95 gpointer mask
; /* Either in_addr * or in6_addr * */
104 static guint signals
[LAST_SIGNAL
] = { 0 };
106 /* Forward declarations. */
108 static void ipv6_network_addr (const struct in6_addr
*addr
,
109 const struct in6_addr
*mask
,
110 struct in6_addr
*res
);
113 ep_free_proxy_host_addr (ProxyHostAddr
*host
)
129 ep_read_key_boolean (EProxy
*proxy
,
132 gboolean res
= FALSE
;
134 g_return_val_if_fail (E_IS_PROXY (proxy
), FALSE
);
137 case E_PROXY_KEY_USE_HTTP_PROXY
:
138 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
139 /* it's not used in the UI, thus behave like always set to TRUE */
140 res
= TRUE
; /* g_settings_get_boolean (proxy->priv->proxy_http_settings, "enabled"); */
142 res
= g_settings_get_boolean (proxy
->priv
->evolution_proxy_settings
, "use-http-proxy");
144 case E_PROXY_KEY_HTTP_USE_AUTH
:
145 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
146 res
= g_settings_get_boolean (proxy
->priv
->proxy_http_settings
, "use-authentication");
148 res
= g_settings_get_boolean (proxy
->priv
->evolution_proxy_settings
, "use-authentication");
151 g_warn_if_reached ();
159 ep_read_key_int (EProxy
*proxy
,
164 g_return_val_if_fail (E_IS_PROXY (proxy
), 0);
167 case E_PROXY_KEY_HTTP_PORT
:
168 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
169 res
= g_settings_get_int (proxy
->priv
->proxy_http_settings
, "port");
171 res
= g_settings_get_int (proxy
->priv
->evolution_proxy_settings
, "http-port");
173 case E_PROXY_KEY_HTTPS_PORT
:
174 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
175 res
= g_settings_get_int (proxy
->priv
->proxy_https_settings
, "port");
177 res
= g_settings_get_int (proxy
->priv
->evolution_proxy_settings
, "secure-port");
179 case E_PROXY_KEY_SOCKS_PORT
:
180 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
181 res
= g_settings_get_int (proxy
->priv
->proxy_socks_settings
, "port");
183 res
= g_settings_get_int (proxy
->priv
->evolution_proxy_settings
, "socks-port");
186 g_warn_if_reached ();
193 /* free returned pointer with g_free() */
195 ep_read_key_string (EProxy
*proxy
,
200 g_return_val_if_fail (E_IS_PROXY (proxy
), NULL
);
203 case E_PROXY_KEY_MODE
:
204 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
205 res
= g_settings_get_string (proxy
->priv
->proxy_settings
, "mode");
207 g_warn_if_reached ();
209 case E_PROXY_KEY_HTTP_HOST
:
210 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
211 res
= g_settings_get_string (proxy
->priv
->proxy_http_settings
, "host");
213 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "http-host");
215 case E_PROXY_KEY_HTTPS_HOST
:
216 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
217 res
= g_settings_get_string (proxy
->priv
->proxy_https_settings
, "host");
219 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "secure-host");
221 case E_PROXY_KEY_SOCKS_HOST
:
222 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
223 res
= g_settings_get_string (proxy
->priv
->proxy_socks_settings
, "host");
225 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "socks-host");
227 case E_PROXY_KEY_HTTP_AUTH_USER
:
228 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
229 res
= g_settings_get_string (proxy
->priv
->proxy_http_settings
, "authentication-user");
231 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "authentication-user");
233 case E_PROXY_KEY_HTTP_AUTH_PWD
:
234 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
235 res
= g_settings_get_string (proxy
->priv
->proxy_http_settings
, "authentication-password");
237 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "authentication-password");
239 case E_PROXY_KEY_AUTOCONFIG_URL
:
240 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
241 res
= g_settings_get_string (proxy
->priv
->proxy_settings
, "autoconfig-url");
243 res
= g_settings_get_string (proxy
->priv
->evolution_proxy_settings
, "autoconfig-url");
246 g_warn_if_reached ();
253 /* list of newly allocated strings, use g_free() for each member and free list itself too */
255 ep_read_key_list (EProxy
*proxy
,
261 g_return_val_if_fail (E_IS_PROXY (proxy
), NULL
);
264 case E_PROXY_KEY_HTTP_IGNORE_HOSTS
:
265 if (proxy
->priv
->type
== PROXY_TYPE_SYSTEM
)
266 strv
= g_settings_get_strv (proxy
->priv
->proxy_settings
, "ignore-hosts");
268 strv
= g_settings_get_strv (proxy
->priv
->evolution_proxy_settings
, "ignore-hosts");
271 g_warn_if_reached ();
278 for (ii
= 0; strv
&& strv
[ii
]; ii
++) {
279 res
= g_slist_prepend (res
, g_strdup (strv
[ii
]));
284 res
= g_slist_reverse (res
);
291 ep_is_in_ignored (EProxy
*proxy
,
298 g_return_val_if_fail (proxy
!= NULL
, FALSE
);
299 g_return_val_if_fail (host
!= NULL
, FALSE
);
302 if (!priv
->ign_hosts
)
305 hn
= g_ascii_strdown (host
, -1);
307 for (l
= priv
->ign_hosts
; l
; l
= l
->next
) {
308 if (*((gchar
*) l
->data
) == '*') {
309 if (g_str_has_suffix (hn
, ((gchar
*) l
->data
) + 1)) {
313 } else if (strcmp (hn
, l
->data
) == 0) {
324 ep_need_proxy_http (EProxy
*proxy
,
327 SoupAddress
*addr
= NULL
;
328 EProxyPrivate
*priv
= proxy
->priv
;
329 ProxyHostAddr
*p_addr
= NULL
;
333 /* check for ignored first */
334 if (ep_is_in_ignored (proxy
, host
))
337 addr
= soup_address_new (host
, 0);
338 status
= soup_address_resolve_sync (addr
, NULL
);
339 if (status
== SOUP_STATUS_OK
) {
341 struct sockaddr
* so_addr
= NULL
;
343 so_addr
= soup_address_get_sockaddr (addr
, &addr_len
);
345 /* This will never happen, since we have already called
346 * soup_address_resolve_sync ().
349 g_object_unref (addr
);
353 if (so_addr
->sa_family
== AF_INET
) {
354 struct in_addr in
, *mask
, *addr_in
;
356 in
= ((struct sockaddr_in
*) so_addr
)->sin_addr
;
357 for (l
= priv
->ign_addrs
; l
; l
= l
->next
) {
358 p_addr
= (ProxyHostAddr
*) l
->data
;
359 if (p_addr
->type
== PROXY_IPV4
) {
360 addr_in
= ((struct in_addr
*) p_addr
->addr
);
361 mask
= ((struct in_addr
*) p_addr
->mask
);
362 if ((in
.s_addr
& mask
->s_addr
) == addr_in
->s_addr
) {
363 d (g_print ("Host [%s] doesn't require proxy\n", host
));
364 g_object_unref (addr
);
370 struct in6_addr in6
, net6
;
371 struct in_addr
*addr_in
, *mask
;
373 in6
= ((struct sockaddr_in6
*) so_addr
)->sin6_addr
;
374 for (l
= priv
->ign_addrs
; l
; l
= l
->next
) {
375 p_addr
= (ProxyHostAddr
*) l
->data
;
376 ipv6_network_addr (&in6
, (struct in6_addr
*) p_addr
->mask
, &net6
);
377 if (p_addr
->type
== PROXY_IPV6
) {
378 if (IN6_ARE_ADDR_EQUAL (&net6
, (struct in6_addr
*) p_addr
->addr
)) {
379 d (g_print ("Host [%s] doesn't require proxy\n", host
));
380 g_object_unref (addr
);
383 } else if (p_addr
->type
== PROXY_IPV6
&&
384 IN6_IS_ADDR_V4MAPPED (&net6
)) {
387 addr_in
= ((struct in_addr
*) p_addr
->addr
);
388 mask
= ((struct in_addr
*) p_addr
->mask
);
390 v4addr
= net6
.s6_addr
[12] << 24
391 | net6
.s6_addr
[13] << 16
392 | net6
.s6_addr
[14] << 8
394 if ((v4addr
& mask
->s_addr
) != addr_in
->s_addr
) {
395 d (g_print ("Host [%s] doesn't require proxy\n", host
));
396 g_object_unref (addr
);
404 d (g_print ("%s needs a proxy to connect to internet\n", host
));
405 g_object_unref (addr
);
411 ep_need_proxy_https (EProxy
*proxy
,
414 /* Can we share ignore list from HTTP at all? */
415 return !ep_is_in_ignored (proxy
, host
);
419 ep_need_proxy_socks (EProxy
*proxy
,
422 /* Can we share ignore list from HTTP at all? */
423 return !ep_is_in_ignored (proxy
, host
);
426 /* Apply a prefix-notation @netmask to the given @addr_in, as described in
427 * http://tools.ietf.org/html/rfc4632#section-3.1 */
429 ep_manipulate_ipv4 (ProxyHostAddr
*host_addr
,
430 struct in_addr
*addr_in
,
433 gboolean has_error
= FALSE
;
434 struct in_addr
*addr
, *mask
;
439 host_addr
->type
= PROXY_IPV4
;
440 addr
= g_new0 (struct in_addr
, 1);
441 memcpy (addr
, addr_in
, sizeof (struct in_addr
));
442 mask
= g_new0 (struct in_addr
, 1);
446 gint width
= strtol (netmask
, &endptr
, 10);
448 if (*endptr
!= '\0' || width
< 0 || width
> 32) {
450 mask
->s_addr
= 0xFFFFFFFF;
451 } else if (width
== 32) {
455 mask
->s_addr
= htonl (~0U << width
);
456 addr
->s_addr
&= mask
->s_addr
;
459 mask
->s_addr
= 0xFFFFFFFF;
462 host_addr
->addr
= addr
;
463 host_addr
->mask
= mask
;
469 ipv6_network_addr (const struct in6_addr
*addr
,
470 const struct in6_addr
*mask
,
471 struct in6_addr
*res
)
475 for (i
= 0; i
< 16; ++i
) {
476 res
->s6_addr
[i
] = addr
->s6_addr
[i
] & mask
->s6_addr
[i
];
481 ep_manipulate_ipv6 (ProxyHostAddr
*host_addr
,
482 struct in6_addr
*addr_in6
,
485 gboolean has_error
= FALSE
;
486 struct in6_addr
*addr
, *mask
;
492 host_addr
->type
= PROXY_IPV6
;
494 addr
= g_new0 (struct in6_addr
, 1);
495 mask
= g_new0 (struct in6_addr
, 1);
497 for (i
= 0; i
< 16; ++i
) {
498 addr
->s6_addr
[i
] = addr_in6
->s6_addr
[i
];
502 gint width
= strtol (netmask
, &endptr
, 10);
504 if (*endptr
!= '\0' || width
< 0 || width
> 128) {
507 for (i
= 0; i
< 16; ++i
) {
508 mask
->s6_addr
[i
] = 0;
510 for (i
= 0; i
< width
/ 8; i
++) {
511 mask
->s6_addr
[i
] = 0xff;
513 mask
->s6_addr
[i
] = (0xff << (8 - width
% 8)) & 0xff;
514 ipv6_network_addr (addr
, mask
, addr
);
516 for (i
= 0; i
< 16; ++i
) {
517 mask
->s6_addr
[i
] = 0xff;
521 host_addr
->addr
= addr
;
522 host_addr
->mask
= mask
;
528 ep_parse_ignore_host (gpointer data
,
531 EProxy
* proxy
= (EProxy
*) user_data
;
532 EProxyPrivate
* priv
= NULL
;
535 gchar
*input
, *netmask
, *hostname
;
536 gboolean has_error
= FALSE
;
538 if (!proxy
|| !proxy
->priv
)
542 input
= (gchar
*) data
;
544 if ((netmask
= strrchr (input
, '/')) != NULL
) {
545 hostname
= g_strndup (input
, netmask
- input
);
548 hostname
= g_ascii_strdown (input
, -1);
551 addr
= soup_address_new (hostname
, 0);
552 status
= soup_address_resolve_sync (addr
, NULL
);
553 if (status
== SOUP_STATUS_OK
) {
554 ProxyHostAddr
*host_addr
;
556 struct sockaddr
* so_addr
= NULL
;
558 host_addr
= g_new0 (ProxyHostAddr
, 1);
560 so_addr
= soup_address_get_sockaddr (addr
, &addr_len
);
562 /* This will never happen, since we have already called
563 * soup_address_resolve_sync ().
566 ep_free_proxy_host_addr (host_addr
);
570 if (so_addr
->sa_family
== AF_INET
)
571 has_error
= ep_manipulate_ipv4 (
573 &((struct sockaddr_in
*) so_addr
)->sin_addr
,
576 has_error
= ep_manipulate_ipv6 (
578 &((struct sockaddr_in6
*) so_addr
)->sin6_addr
,
582 priv
->ign_addrs
= g_slist_append (
583 priv
->ign_addrs
, host_addr
);
584 priv
->ign_hosts
= g_slist_append (
585 priv
->ign_hosts
, hostname
);
587 ep_free_proxy_host_addr (host_addr
);
591 d (g_print ("Unable to resolve %s\n", hostname
));
592 priv
->ign_hosts
= g_slist_append (priv
->ign_hosts
, hostname
);
595 g_object_unref (addr
);
599 ep_change_uri (SoupURI
**soup_uri
,
602 gboolean changed
= FALSE
;
604 g_return_val_if_fail (soup_uri
!= NULL
, FALSE
);
608 soup_uri_free (*soup_uri
);
612 } else if (*soup_uri
) {
613 gchar
*old
= soup_uri_to_string (*soup_uri
, FALSE
);
616 gint len
= strlen (old
);
618 /* remove ending slash, if there */
619 if (old
[len
- 1] == '/')
623 changed
= old
&& uri
&& g_ascii_strcasecmp (old
, uri
) != 0;
625 soup_uri_free (*soup_uri
);
626 *soup_uri
= soup_uri_new (uri
);
631 *soup_uri
= soup_uri_new (uri
);
639 update_proxy_uri (const gchar
*uri
,
640 const gchar
*proxy_user
,
641 const gchar
*proxy_pw
)
643 gchar
*res
, *user
= NULL
, *pw
= NULL
;
646 g_return_val_if_fail (uri
!= NULL
, NULL
);
648 if (proxy_user
&& *proxy_user
) {
649 user
= soup_uri_encode (proxy_user
, ":/;#@?\\");
651 pw
= soup_uri_encode (proxy_pw
, ":/;#@?\\");
655 return g_strdup (uri
);
657 /* here can be only http or https and nothing else */
658 is_https
= g_str_has_prefix (uri
, "https://");
660 res
= g_strdup_printf (
662 is_https
? "https" : "http",
666 uri
+ strlen ("http://") + (is_https
? 1 : 0));
675 ep_set_proxy (EProxy
*proxy
,
676 gboolean regen_ign_host_list
)
678 gchar
*proxy_server
, *uri_http
= NULL
, *uri_https
= NULL
, *uri_socks
= NULL
;
679 gint proxy_port
, old_type
;
680 EProxyPrivate
* priv
= proxy
->priv
;
682 gboolean changed
= FALSE
, sys_manual
= TRUE
;
684 old_type
= priv
->type
;
685 priv
->type
= g_settings_get_int (priv
->evolution_proxy_settings
, "proxy-type");
686 if (priv
->type
> PROXY_TYPE_AUTO_URL
)
687 priv
->type
= PROXY_TYPE_SYSTEM
;
688 changed
= priv
->type
!= old_type
;
690 if (priv
->type
== PROXY_TYPE_SYSTEM
) {
691 gchar
*mode
= ep_read_key_string (proxy
, E_PROXY_KEY_MODE
);
693 /* supporting only manual system proxy setting */
694 sys_manual
= mode
&& g_str_equal (mode
, "manual");
699 priv
->use_proxy
= ep_read_key_boolean (proxy
, E_PROXY_KEY_USE_HTTP_PROXY
);
700 if (!priv
->use_proxy
|| priv
->type
== PROXY_TYPE_NO_PROXY
|| !sys_manual
) {
701 changed
= ep_change_uri (&priv
->uri_http
, NULL
) || changed
;
702 changed
= ep_change_uri (&priv
->uri_https
, NULL
) || changed
;
703 changed
= ep_change_uri (&priv
->uri_socks
, NULL
) || changed
;
707 proxy_server
= ep_read_key_string (proxy
, E_PROXY_KEY_HTTP_HOST
);
708 proxy_port
= ep_read_key_int (proxy
, E_PROXY_KEY_HTTP_PORT
);
709 if (proxy_server
!= NULL
&& *proxy_server
&& !g_ascii_isspace (*proxy_server
)) {
711 uri_http
= g_strdup_printf ("http://%s:%d", proxy_server
, proxy_port
);
713 uri_http
= g_strdup_printf ("http://%s", proxy_server
);
716 g_free (proxy_server
);
717 d (g_print ("ep_set_proxy: uri_http: %s\n", uri_http
));
719 proxy_server
= ep_read_key_string (proxy
, E_PROXY_KEY_HTTPS_HOST
);
720 proxy_port
= ep_read_key_int (proxy
, E_PROXY_KEY_HTTPS_PORT
);
721 if (proxy_server
!= NULL
&& *proxy_server
&& !g_ascii_isspace (*proxy_server
)) {
723 uri_https
= g_strdup_printf ("https://%s:%d", proxy_server
, proxy_port
);
725 uri_https
= g_strdup_printf ("https://%s", proxy_server
);
728 g_free (proxy_server
);
729 d (g_print ("ep_set_proxy: uri_https: %s\n", uri_https
));
731 proxy_server
= ep_read_key_string (proxy
, E_PROXY_KEY_SOCKS_HOST
);
732 proxy_port
= ep_read_key_int (proxy
, E_PROXY_KEY_SOCKS_PORT
);
733 if (proxy_server
!= NULL
&& *proxy_server
&& !g_ascii_isspace (*proxy_server
)) {
735 uri_socks
= g_strdup_printf ("socks://%s:%d", proxy_server
, proxy_port
);
737 uri_socks
= g_strdup_printf ("socks://%s", proxy_server
);
740 g_free (proxy_server
);
741 d (g_print ("ep_set_proxy: uri_socks: %s\n", uri_socks
));
743 if (regen_ign_host_list
) {
744 if (priv
->ign_hosts
) {
745 g_slist_foreach (priv
->ign_hosts
, (GFunc
) g_free
, NULL
);
746 g_slist_free (priv
->ign_hosts
);
747 priv
->ign_hosts
= NULL
;
750 if (priv
->ign_addrs
) {
751 g_slist_foreach (priv
->ign_addrs
, (GFunc
) ep_free_proxy_host_addr
, NULL
);
752 g_slist_free (priv
->ign_addrs
);
753 priv
->ign_addrs
= NULL
;
756 ignore
= ep_read_key_list (proxy
, E_PROXY_KEY_HTTP_IGNORE_HOSTS
);
758 g_slist_foreach (ignore
, (GFunc
) ep_parse_ignore_host
, proxy
);
759 g_slist_foreach (ignore
, (GFunc
) g_free
, NULL
);
760 g_slist_free (ignore
);
764 if (ep_read_key_boolean (proxy
, E_PROXY_KEY_HTTP_USE_AUTH
)) {
765 gchar
*proxy_user
, *proxy_pw
, *tmp
= NULL
, *tmps
= NULL
;
767 proxy_user
= ep_read_key_string (proxy
, E_PROXY_KEY_HTTP_AUTH_USER
);
768 proxy_pw
= ep_read_key_string (proxy
, E_PROXY_KEY_HTTP_AUTH_PWD
);
770 if (uri_http
&& proxy_user
&& *proxy_user
) {
772 uri_http
= update_proxy_uri (uri_http
, proxy_user
, proxy_pw
);
775 if (uri_https
&& proxy_user
&& *proxy_user
) {
777 uri_https
= update_proxy_uri (uri_https
, proxy_user
, proxy_pw
);
786 changed
= ep_change_uri (&priv
->uri_http
, uri_http
) || changed
;
787 changed
= ep_change_uri (&priv
->uri_https
, uri_https
) || changed
;
788 changed
= ep_change_uri (&priv
->uri_socks
, uri_socks
) || changed
;
796 G_STRFUNC
, changed
? 1 : 0,
797 uri_http
? uri_http
: "[null]",
798 uri_https
? uri_https
: "[null]",
799 uri_socks
? uri_socks
: "[null]"));
801 g_signal_emit (proxy
, signals
[CHANGED
], 0);
809 ep_evo_proxy_changed_cb (GSettings
*settings
,
815 g_return_if_fail (E_IS_PROXY (proxy
));
819 d (g_print ("%s: proxy settings changed, key '%s'\n", G_STRFUNC
, key
? key
: "NULL"));
820 if (g_strcmp0 (key
, "proxy-type") == 0) {
821 ep_set_proxy (proxy
, TRUE
);
822 } else if (priv
->type
== PROXY_TYPE_SYSTEM
) {
826 ep_set_proxy (proxy
, g_strcmp0 (key
, "ignore-hosts") == 0);
830 ep_sys_proxy_changed_cb (GSettings
*settings
,
834 g_return_if_fail (proxy
!= NULL
);
836 if (proxy
->priv
->type
!= PROXY_TYPE_SYSTEM
)
839 ep_set_proxy (proxy
, g_strcmp0 (key
, "ignore-hosts") == 0);
843 ep_sys_proxy_http_changed_cb (GSettings
*settings
,
847 g_return_if_fail (proxy
!= NULL
);
849 if (proxy
->priv
->type
!= PROXY_TYPE_SYSTEM
)
852 ep_set_proxy (proxy
, FALSE
);
856 ep_sys_proxy_https_changed_cb (GSettings
*settings
,
860 g_return_if_fail (proxy
!= NULL
);
862 if (proxy
->priv
->type
!= PROXY_TYPE_SYSTEM
)
865 ep_set_proxy (proxy
, FALSE
);
869 ep_sys_proxy_socks_changed_cb (GSettings
*settings
,
873 g_return_if_fail (proxy
!= NULL
);
875 if (proxy
->priv
->type
!= PROXY_TYPE_SYSTEM
)
878 ep_set_proxy (proxy
, FALSE
);
882 e_proxy_dispose (GObject
*object
)
887 proxy
= E_PROXY (object
);
890 if (priv
->evolution_proxy_settings
) {
891 g_signal_handlers_disconnect_by_func (priv
->evolution_proxy_settings
, ep_evo_proxy_changed_cb
, proxy
);
892 g_object_unref (priv
->evolution_proxy_settings
);
893 priv
->evolution_proxy_settings
= NULL
;
896 if (priv
->proxy_settings
) {
897 g_signal_handlers_disconnect_by_func (priv
->proxy_settings
, ep_sys_proxy_changed_cb
, proxy
);
898 g_object_unref (priv
->proxy_settings
);
899 priv
->proxy_settings
= NULL
;
902 if (priv
->proxy_http_settings
) {
903 g_signal_handlers_disconnect_by_func (priv
->proxy_http_settings
, ep_sys_proxy_http_changed_cb
, proxy
);
904 g_object_unref (priv
->proxy_http_settings
);
905 priv
->proxy_http_settings
= NULL
;
908 if (priv
->proxy_https_settings
) {
909 g_signal_handlers_disconnect_by_func (priv
->proxy_https_settings
, ep_sys_proxy_https_changed_cb
, proxy
);
910 g_object_unref (priv
->proxy_https_settings
);
911 priv
->proxy_https_settings
= NULL
;
914 if (priv
->proxy_socks_settings
) {
915 g_signal_handlers_disconnect_by_func (priv
->proxy_socks_settings
, ep_sys_proxy_socks_changed_cb
, proxy
);
916 g_object_unref (priv
->proxy_socks_settings
);
917 priv
->proxy_socks_settings
= NULL
;
921 soup_uri_free (priv
->uri_http
);
924 soup_uri_free (priv
->uri_https
);
927 soup_uri_free (priv
->uri_socks
);
929 g_slist_foreach (priv
->ign_hosts
, (GFunc
) g_free
, NULL
);
930 g_slist_free (priv
->ign_hosts
);
932 g_slist_foreach (priv
->ign_addrs
, (GFunc
) ep_free_proxy_host_addr
, NULL
);
933 g_slist_free (priv
->ign_addrs
);
935 /* Chain up to parent's dispose() method. */
936 G_OBJECT_CLASS (e_proxy_parent_class
)->dispose (object
);
940 e_proxy_class_init (EProxyClass
*class)
942 GObjectClass
*object_class
;
944 g_type_class_add_private (class, sizeof (EProxyPrivate
));
946 object_class
= G_OBJECT_CLASS (class);
947 object_class
->dispose
= e_proxy_dispose
;
951 * @proxy: the #EProxy which emitted the signal
953 * Emitted when proxy settings changes.
955 signals
[CHANGED
] = g_signal_new (
957 G_OBJECT_CLASS_TYPE (object_class
),
959 G_STRUCT_OFFSET (EProxyClass
, changed
),
966 e_proxy_init (EProxy
*proxy
)
968 proxy
->priv
= E_PROXY_GET_PRIVATE (proxy
);
970 proxy
->priv
->type
= PROXY_TYPE_SYSTEM
;
972 proxy
->priv
->evolution_proxy_settings
= g_settings_new ("org.gnome.evolution.shell.network-config");
973 proxy
->priv
->proxy_settings
= g_settings_new ("org.gnome.system.proxy");
974 proxy
->priv
->proxy_http_settings
= g_settings_get_child (proxy
->priv
->proxy_settings
, "http");
975 proxy
->priv
->proxy_https_settings
= g_settings_get_child (proxy
->priv
->proxy_settings
, "https");
976 proxy
->priv
->proxy_socks_settings
= g_settings_get_child (proxy
->priv
->proxy_settings
, "socks");
978 g_signal_connect (proxy
->priv
->evolution_proxy_settings
, "changed", G_CALLBACK (ep_evo_proxy_changed_cb
), proxy
);
979 g_signal_connect (proxy
->priv
->proxy_settings
, "changed", G_CALLBACK (ep_sys_proxy_changed_cb
), proxy
);
980 g_signal_connect (proxy
->priv
->proxy_http_settings
, "changed", G_CALLBACK (ep_sys_proxy_http_changed_cb
), proxy
);
981 g_signal_connect (proxy
->priv
->proxy_https_settings
, "changed", G_CALLBACK (ep_sys_proxy_https_changed_cb
), proxy
);
982 g_signal_connect (proxy
->priv
->proxy_socks_settings
, "changed", G_CALLBACK (ep_sys_proxy_socks_changed_cb
), proxy
);
988 * Returns: (transfer full): a new instance of an #EProxy
995 return g_object_new (E_TYPE_PROXY
, NULL
);
999 * e_proxy_setup_proxy:
1000 * @proxy: an #EProxy
1002 * Sets up internal structure members and reads the proxy settings.
1007 e_proxy_setup_proxy (EProxy
*proxy
)
1009 g_return_if_fail (E_IS_PROXY (proxy
));
1011 /* We get the evolution-shell proxy keys here
1012 * set soup up to use the proxy,
1013 * and listen to any changes */
1015 /* XXX Why can't we do this automatically in constructed() ? */
1017 ep_set_proxy (proxy
, TRUE
);
1021 * e_proxy_peek_uri_for:
1022 * @proxy: an #EProxy
1025 * Returns: (transfer none): A proxy URI (as a #SoupURI) which the given @uri
1026 * may use, based on its scheme
1031 e_proxy_peek_uri_for (EProxy
*proxy
,
1034 SoupURI
*res
= NULL
;
1037 g_return_val_if_fail (E_IS_PROXY (proxy
), NULL
);
1038 g_return_val_if_fail (uri
!= NULL
, NULL
);
1040 soup_uri
= soup_uri_new (uri
);
1041 if (soup_uri
== NULL
)
1044 if (soup_uri
->scheme
== SOUP_URI_SCHEME_HTTP
)
1045 res
= proxy
->priv
->uri_http
;
1046 else if (soup_uri
->scheme
== SOUP_URI_SCHEME_HTTPS
)
1047 res
= proxy
->priv
->uri_https
;
1048 else if (soup_uri
->scheme
&& g_ascii_strcasecmp (soup_uri
->scheme
, "socks") == 0)
1049 res
= proxy
->priv
->uri_socks
;
1051 soup_uri_free (soup_uri
);
1057 * e_proxy_require_proxy_for_uri:
1058 * @proxy: an #EProxy
1061 * Returns: Whether the @uri requires proxy to connect to it
1066 e_proxy_require_proxy_for_uri (EProxy
*proxy
,
1069 SoupURI
*soup_uri
= NULL
;
1070 gboolean need_proxy
= FALSE
;
1072 g_return_val_if_fail (E_IS_PROXY (proxy
), FALSE
);
1073 g_return_val_if_fail (uri
!= NULL
, FALSE
);
1075 if (!proxy
->priv
->use_proxy
|| proxy
->priv
->type
== PROXY_TYPE_NO_PROXY
) {
1076 d (g_print ("[%s] don't need a proxy to connect to internet\n", uri
));
1080 soup_uri
= soup_uri_new (uri
);
1081 if (soup_uri
== NULL
)
1084 if (soup_uri
->scheme
== SOUP_URI_SCHEME_HTTP
)
1085 need_proxy
= ep_need_proxy_http (proxy
, soup_uri
->host
);
1086 else if (soup_uri
->scheme
== SOUP_URI_SCHEME_HTTPS
)
1087 need_proxy
= ep_need_proxy_https (proxy
, soup_uri
->host
);
1088 else if (soup_uri
->scheme
&& g_ascii_strcasecmp (soup_uri
->scheme
, "socks") == 0)
1089 need_proxy
= ep_need_proxy_socks (proxy
, soup_uri
->host
);
1091 soup_uri_free (soup_uri
);