[evolution] I#39 - Extend Mail autoconfig to check in server's autoconfiguration too
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#39 - Extend Mail autoconfig to check in server's autoconfiguration too
- Date: Tue, 10 Jul 2018 18:08:25 +0000 (UTC)
commit 600351ef67482e725308f145bb714a4a507af07a
Author: Milan Crha <mcrha redhat com>
Date: Tue Jul 10 20:01:29 2018 +0200
I#39 - Extend Mail autoconfig to check in server's autoconfiguration too
Closes https://gitlab.gnome.org/GNOME/evolution/issues/39
src/mail/e-mail-autoconfig.c | 185 +++++++++++++++++++++++++++++--------------
1 file changed, 127 insertions(+), 58 deletions(-)
---
diff --git a/src/mail/e-mail-autoconfig.c b/src/mail/e-mail-autoconfig.c
index 3464936974..b0e414fa74 100644
--- a/src/mail/e-mail-autoconfig.c
+++ b/src/mail/e-mail-autoconfig.c
@@ -77,6 +77,8 @@
#define AUTOCONFIG_BASE_URI "https://autoconfig.thunderbird.net/v1.1/"
+#define FAKE_EVOLUTION_USER_STRING "EVOLUTIONUSER"
+
#define ERROR_IS_NOT_FOUND(error) \
(g_error_matches ((error), SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND))
@@ -185,16 +187,54 @@ mail_autoconfig_parse_end_element (GMarkupParseContext *context,
closure->result = NULL;
}
+/* Returns NULL when not being there */
+static gchar *
+mail_autoconfig_replace_case_insensitive (const gchar *text,
+ const gchar *before,
+ const gchar *after)
+{
+ const gchar *p, *next;
+ GString *str;
+ gint find_len;
+
+ if (!text)
+ return NULL;
+
+ find_len = strlen (before);
+ str = g_string_new ("");
+
+ p = text;
+ while (next = camel_strstrcase (p, before), next) {
+ if (p < next)
+ g_string_append_len (str, p, next - p);
+
+ if (after && *after)
+ g_string_append (str, after);
+
+ p = next + find_len;
+ }
+
+ if (p == text) {
+ g_string_free (str, TRUE);
+ return NULL;
+ }
+
+ g_string_append (str, p);
+
+ return g_string_free (str, FALSE);
+}
+
static void
mail_autoconfig_parse_text (GMarkupParseContext *context,
- const gchar *text,
- gsize text_length,
+ const gchar *in_text,
+ gsize in_text_length,
gpointer user_data,
GError **error)
{
ParserClosure *closure = user_data;
EMailAutoconfigPrivate *priv;
- const gchar *element_name;
+ const gchar *element_name, *text;
+ gchar *to_free;
GString *string;
priv = closure->autoconfig->priv;
@@ -202,6 +242,9 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
if (closure->result == NULL)
return;
+ to_free = mail_autoconfig_replace_case_insensitive (in_text, FAKE_EVOLUTION_USER_STRING,
priv->email_local_part);
+ text = to_free ? to_free : in_text;
+
/* Perform the following text substitutions:
*
* %EMAILADDRESS% : closure->email_address
@@ -332,6 +375,7 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
}
g_string_free (string, TRUE);
+ g_free (to_free);
}
static GMarkupParser mail_autoconfig_parser = {
@@ -374,22 +418,78 @@ mail_autoconfig_abort_soup_session_cb (GCancellable *cancellable,
soup_session_abort (soup_session);
}
+static gboolean
+mail_autoconfig_lookup_uri_sync (EMailAutoconfig *autoconfig,
+ const gchar *uri,
+ SoupSession *soup_session,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *soup_message;
+ gboolean success;
+ guint status;
+
+ soup_message = soup_message_new (SOUP_METHOD_GET, uri);
+
+ if (!soup_message) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Invalid URI: ā%sā"), uri);
+ return FALSE;
+ }
+
+ soup_message_headers_append (
+ soup_message->request_headers,
+ "User-Agent", "Evolution/" VERSION VERSION_SUBSTRING " " VERSION_COMMENT);
+
+ status = soup_session_send_message (soup_session, soup_message);
+
+ success = SOUP_STATUS_IS_SUCCESSFUL (status);
+
+ if (success) {
+ GMarkupParseContext *context;
+ ParserClosure closure;
+
+ closure.autoconfig = autoconfig;
+ closure.result = NULL;
+
+ context = g_markup_parse_context_new (
+ &mail_autoconfig_parser, 0,
+ &closure, (GDestroyNotify) NULL);
+
+ success = g_markup_parse_context_parse (
+ context,
+ soup_message->response_body->data,
+ soup_message->response_body->length,
+ error);
+
+ if (success)
+ success = g_markup_parse_context_end_parse (context, error);
+
+ g_markup_parse_context_free (context);
+ } else {
+ g_set_error_literal (
+ error, SOUP_HTTP_ERROR,
+ soup_message->status_code,
+ soup_message->reason_phrase);
+ }
+
+ g_object_unref (soup_message);
+
+ return success;
+}
+
static gboolean
mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
const gchar *domain,
GCancellable *cancellable,
GError **error)
{
- GMarkupParseContext *context;
ESourceRegistry *registry;
ESource *proxy_source;
- SoupMessage *soup_message;
SoupSession *soup_session;
- ParserClosure closure;
gulong cancel_id = 0;
- gboolean success;
- guint status;
gchar *uri;
+ gboolean success = FALSE;
registry = e_mail_autoconfig_get_registry (autoconfig);
proxy_source = e_source_registry_ref_builtin_proxy (registry);
@@ -401,26 +501,6 @@ mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
g_object_unref (proxy_source);
- uri = g_strconcat (AUTOCONFIG_BASE_URI, domain, NULL);
-
- soup_message = soup_message_new (SOUP_METHOD_GET, uri);
-
- if (!soup_message) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid URI: ā%sā"), uri);
-
- g_object_unref (soup_session);
- g_free (uri);
-
- return FALSE;
- }
-
- g_free (uri);
-
- soup_message_headers_append (
- soup_message->request_headers,
- "User-Agent", "Evolution/" VERSION VERSION_SUBSTRING " " VERSION_COMMENT);
-
if (G_IS_CANCELLABLE (cancellable))
cancel_id = g_cancellable_connect (
cancellable,
@@ -428,41 +508,30 @@ mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
g_object_ref (soup_session),
(GDestroyNotify) g_object_unref);
- status = soup_session_send_message (soup_session, soup_message);
-
- if (cancel_id > 0)
- g_cancellable_disconnect (cancellable, cancel_id);
-
- success = SOUP_STATUS_IS_SUCCESSFUL (status);
-
- if (!success) {
- g_set_error_literal (
- error, SOUP_HTTP_ERROR,
- soup_message->status_code,
- soup_message->reason_phrase);
- goto exit;
+ /* First try user configuration in autoconfig.$DOMAIN URL and ignore error */
+ if (!success && !g_cancellable_is_cancelled (cancellable)) {
+ uri = g_strconcat ("http://autoconfig.", domain, "/mail/config-v1.1.xml?emailaddress="
FAKE_EVOLUTION_USER_STRING "%40", domain, NULL);
+ success = mail_autoconfig_lookup_uri_sync (autoconfig, uri, soup_session, cancellable, NULL);
+ g_free (uri);
}
- closure.autoconfig = autoconfig;
- closure.result = NULL;
-
- context = g_markup_parse_context_new (
- &mail_autoconfig_parser, 0,
- &closure, (GDestroyNotify) NULL);
-
- success = g_markup_parse_context_parse (
- context,
- soup_message->response_body->data,
- soup_message->response_body->length,
- error);
+ /* Then with $DOMAIN/.well-known/autoconfig/ and ignore error */
+ if (!success && !g_cancellable_is_cancelled (cancellable)) {
+ uri = g_strconcat ("http://", domain,
"/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=" FAKE_EVOLUTION_USER_STRING "%40", domain, NULL);
+ success = mail_autoconfig_lookup_uri_sync (autoconfig, uri, soup_session, cancellable, NULL);
+ g_free (uri);
+ }
- if (success)
- success = g_markup_parse_context_end_parse (context, error);
+ /* Final, try the upstream ISPDB and propagate error */
+ if (!success && !g_cancellable_is_cancelled (cancellable)) {
+ uri = g_strconcat (AUTOCONFIG_BASE_URI, domain, NULL);
+ success = mail_autoconfig_lookup_uri_sync (autoconfig, uri, soup_session, cancellable, error);
+ g_free (uri);
+ }
- g_markup_parse_context_free (context);
+ if (cancel_id > 0)
+ g_cancellable_disconnect (cancellable, cancel_id);
-exit:
- g_object_unref (soup_message);
g_object_unref (soup_session);
return success;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]