Make federated_url_for_address() return the same thing whether a
[claws.git] / src / plugins / libravatar / libravatar_federation.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2014 Hiroyuki Yamamoto and the Claws Mail Team
4  * Copyright (C) 2014 Ricardo Mones
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21
22 #include "libravatar_federation.h"
23 #include "libravatar_prefs.h"
24 #include "utils.h"
25 #include "gtkutils.h"
26
27 #define MISSING "x"
28
29 static GHashTable *federated = NULL;
30
31 /**
32  * Get the associated avatar URL for a domain.
33  *
34  * @param domain Domain to get the URL for.
35  *
36  * @return The avatar URL for the domain or NULL if not found.
37  */
38 static gchar *get_federated_url_for_domain(const gchar *domain)
39 {
40         gchar *found;
41
42         if (federated == NULL) {
43                 return NULL;
44         }
45
46         found = (gchar *) g_hash_table_lookup(federated, domain);
47
48         if (found != NULL)
49                 debug_print("cached avatar url for domain %s found: %s\n", domain, found);
50         else    
51                 debug_print("cached avatar url for domain %s not found\n", domain);
52
53         return found;
54 }
55
56 /**
57  * Adds a URL for a domain.
58  *
59  * @param url  The computed avatar URL.
60  * @param domain  Associated domain.
61  */
62 static void add_federated_url_for_domain(const gchar *url, const gchar *domain)
63 {
64         if (url == NULL)
65                 return;
66
67         if (federated == NULL)
68                 federated = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
69
70         debug_print("new cached avatar url for domain %s: %s\n", domain, url);
71         g_hash_table_insert(federated, g_strdup(domain), g_strdup(url)); 
72 }
73
74 /**
75  * Retrieves the federated URL for a given email address.
76  *
77  * @param address  The email address.
78  *
79  * @return The avatar URL for the domain of the address. 
80  */
81 gchar *federated_url_for_address(const gchar *address)
82 {
83         gchar *domain = NULL, *last = NULL, *addr = NULL, *url = NULL;
84         gchar *host = NULL;
85         guint16 port = 0;
86
87         if (address == NULL || *address == '\0')
88                 goto invalid_addr;
89
90         addr = g_strdup(address);
91         domain = strchr(addr, '@');
92         if (domain == NULL)
93                 goto invalid_addr;
94  
95         ++domain;
96         if (strlen(domain) < 5)
97                 goto invalid_addr;
98
99         last = domain;
100         while (*last != '\0' && *last != ' ' && *last != '\t' && *last != '>')
101                 ++last;
102         *last = '\0';
103
104         /* try cached domains */
105         url = get_federated_url_for_domain(domain);
106         if (url != NULL) {
107                 g_free(addr);
108                 if (!strcmp(url, MISSING)) {
109                         return NULL;
110                 }
111                 return g_strdup(url);
112         }
113
114         /* not cached, try secure service first */
115         if (auto_configure_service_sync("avatars-sec", domain, &host, &port)) {
116                 if (port != 443) {
117                         url = g_strdup_printf("https://%s:%d/avatar", host, port);
118                 } else {
119                         url = g_strdup_printf("https://%s/avatar", host);
120                 }
121         } else { /* try standard one if no secure service available */
122                 if (auto_configure_service_sync("avatars", domain, &host, &port)) {
123                         if (port != 80) {
124                                 url = g_strdup_printf("http://%s:%d/avatar", host, port);
125                         } else {
126                                 url = g_strdup_printf("http://%s/avatar", host);
127                         }
128                 } else {
129                         debug_print("libravatar federated domain for %s not found\n", domain);
130                 }
131         }
132         if (url != NULL) {
133                 add_federated_url_for_domain(url, domain);
134         } else {
135                 add_federated_url_for_domain(MISSING, domain);
136         }
137
138         g_free(addr);
139         return url;
140
141 invalid_addr:
142         if (addr != NULL)
143                 g_free(addr);
144
145         debug_print("invalid address for libravatar federated domain\n");
146         return NULL;
147 }
148