commit 31a6fd3dbf12e70a177eb852df81be2c142c59f3
Author: Milan Crha <mcrha@redhat.com>
Date:   Tue Mar 13 15:28:11 2012 +0530

    Bug #664116 - Fetch URL doesn't always work

diff --git a/src/account-setup-eplugin/exchange-ews-account-setup.c b/src/account-setup-eplugin/exchange-ews-account-setup.c
index 7106f60..a1b9eb7 100644
--- a/src/account-setup-eplugin/exchange-ews-account-setup.c
+++ b/src/account-setup-eplugin/exchange-ews-account-setup.c
@@ -169,14 +169,21 @@ validate_credentials (GtkWidget *widget, struct _AutoDiscCallBackData *cbdata)
 {
 	EConfig *config = cbdata->config;
 	EMConfigTargetAccount *target_account = (EMConfigTargetAccount *)(config->target);
-	gchar *password = NULL;
+	gchar *password = NULL, *url_str = NULL;
+	CamelURL *url=NULL;
 
 	password = get_password (target_account);
 	/*Can there be a account without password ?*/
 	if (password && *password) {
+		url = camel_url_new (e_account_get_string (get_modified_account (target_account), E_ACCOUNT_SOURCE_URL), NULL);
+		url_str = camel_url_to_string (url, 0);
 		e_ews_autodiscover_ws_url (autodiscover_callback, cbdata,
 					   (get_modified_account (target_account))->id->address,
-					   password);
+					   password,
+					   url_str,
+					   url->user);
+		g_free (url_str);
+		camel_url_free (url);
 	}
 	g_free (password);
 }
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index c4beb70..0ac96d0 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -1008,7 +1008,7 @@ struct _autodiscover_data {
 	EEwsConnection *cnc;
 	xmlOutputBuffer *buf;
 	GSimpleAsyncResult *simple;
-	SoupMessage *msgs[2];
+	SoupMessage *msgs[4];
 	EEwsAutoDiscoverCallback cb;
 	gpointer cbdata;
 };
@@ -1062,11 +1062,11 @@ autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer data)
 	int idx;
 	gboolean success = FALSE;
 
-	for (idx = 0; idx < 2; idx++) {
+	for (idx = 0; idx < 4; idx++) {
 		if (ad->msgs[idx] == msg)
 			break;
 	}
-	if (idx == 2) {
+	if (idx == 4) {
 		/* We already got removed (cancelled). Do nothing */
 		return;
 	}
@@ -1145,7 +1145,7 @@ autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer data)
 	}
 
 	/* We have a good response; cancel all the others */
-	for (idx = 0; idx < 2; idx++) {
+	for (idx = 0; idx < 4; idx++) {
 		if (ad->msgs[idx]) {
 			SoupMessage *m = ad->msgs[idx];
 			ad->msgs[idx] = NULL;
@@ -1160,7 +1160,7 @@ autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer data)
 	return;
 
 failed:
-	for (idx = 0; idx < 2; idx++) {
+	for (idx = 0; idx < 4; idx++) {
 		if (ad->msgs[idx]) {
 			/* There's another request outstanding.
 			   Hope that it has better luck. */
@@ -1224,15 +1224,17 @@ e_ews_get_msg_for_url (const gchar *url, xmlOutputBuffer *buf)
 
 void
 e_ews_autodiscover_ws_url (EEwsAutoDiscoverCallback cb, gpointer cbdata,
-			   const gchar *email, const gchar *password)
+			   const gchar *email, const gchar *password,
+			   const gchar *ews_url, const gchar *username)
 {
 	struct _autodiscover_data *ad;
 	xmlOutputBuffer *buf;
 	GError *error = NULL;
-	gchar *url;
+	gchar *url1, *url2, *url3, *url4;
 	gchar *domain;
 	xmlDoc *doc;
 	EEwsConnection *cnc;
+	gboolean use_secure = TRUE;
 
 	if (!password || !email) {
 		g_set_error (&error, EWS_CONNECTION_ERROR,
@@ -1253,11 +1255,33 @@ e_ews_autodiscover_ws_url (EEwsAutoDiscoverCallback cb, gpointer cbdata,
 	xmlNodeDumpOutput(buf, doc, xmlDocGetRootElement(doc), 0, 1, NULL);
 	xmlOutputBufferFlush(buf);
 
-	url = g_strdup_printf("https://%s/autodiscover/autodiscover.xml", domain);
+	url1 = NULL;
+	url2 = NULL;
+	url3 = NULL;
+	url4 = NULL;
+	if (ews_url) {
+		SoupURI *uri = soup_uri_new (ews_url);
 
-	/* FIXME: Get username from config; don't assume same as email */
-	cnc = e_ews_connection_new (url, email, password, NULL, NULL, &error);
+		if (uri) {
+			use_secure = g_strcmp0 (soup_uri_get_scheme (uri), "https") == 0;
+
+			url1 = g_strdup_printf ("http%s://%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", soup_uri_get_host (uri));
+			url2 = g_strdup_printf ("http%s://autodiscover.%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", soup_uri_get_host (uri));
+			soup_uri_free (uri);
+		}
+	} 
+
+	url3 = g_strdup_printf ("http%s://%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", domain);
+	url4 = g_strdup_printf ("http%s://autodiscover.%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", domain);
+
+	cnc = e_ews_connection_new (url3, (username && *username) ? username : email, password, NULL, NULL, &error);
 	if (!cnc) {
+		g_free (url1);
+		g_free (url2);
+		g_free (url3);
+		g_free (url4);
+		xmlOutputBufferClose (buf);
+		xmlFreeDoc (doc);
 	err:
 		cb (NULL, cbdata, error);
 		return;
@@ -1278,12 +1302,10 @@ e_ews_autodiscover_ws_url (EEwsAutoDiscoverCallback cb, gpointer cbdata,
 	ad->buf = buf;
 	ad->simple = g_simple_async_result_new (G_OBJECT (cnc), autodiscover_done_cb,
 					    ad, e_ews_autodiscover_ws_url);
-	ad->msgs[0] = e_ews_get_msg_for_url (url, buf);
-	g_free (url);
-
-	url = g_strdup_printf("https://autodiscover.%s/autodiscover/autodiscover.xml", domain);
-	ad->msgs[1] = e_ews_get_msg_for_url (url, buf);
-	g_free (url);
+	ad->msgs[0] = url1 ? e_ews_get_msg_for_url (url1, buf) : NULL;
+	ad->msgs[1] = url2 ? e_ews_get_msg_for_url (url2, buf) : NULL;
+	ad->msgs[2] = url3 ? e_ews_get_msg_for_url (url3, buf) : NULL;
+	ad->msgs[3] = url4 ? e_ews_get_msg_for_url (url4, buf) : NULL;
 
 	/* These have to be submitted only after they're both set in ad->msgs[]
 	   or there will be races with fast completion */
@@ -1291,13 +1313,20 @@ e_ews_autodiscover_ws_url (EEwsAutoDiscoverCallback cb, gpointer cbdata,
 				    autodiscover_response_cb, ad);
 	soup_session_queue_message (cnc->priv->soup_session, ad->msgs[1],
 				    autodiscover_response_cb, ad);
+	soup_session_queue_message (cnc->priv->soup_session, ad->msgs[2],
+				    autodiscover_response_cb, ad);
+	soup_session_queue_message (cnc->priv->soup_session, ad->msgs[3],
+				    autodiscover_response_cb, ad);
 
 	g_object_unref (cnc); /* the GSimpleAsyncResult holds it now */
 
 	xmlFreeDoc (doc);
+	g_free (url1);
+	g_free (url2);
+	g_free (url3);
+	g_free (url4);
 }
 
-
 struct _oal_req_data {
 	EEwsConnection *cnc;
 	GSimpleAsyncResult *simple;
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 03d4860..3c2a26f 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -134,7 +134,9 @@ typedef void (*EEwsAutoDiscoverCallback) (EwsUrls *urls, gpointer user_data, GEr
 void		e_ews_autodiscover_ws_url	(EEwsAutoDiscoverCallback cb,
 						 gpointer cbdata,
 						 const gchar *email,
-						 const gchar *password);
+						 const gchar *password,
+						 const gchar *ews_url,
+						 const gchar *username);
 void		e_ews_connection_set_mailbox	(EEwsConnection *cnc,
 						 const gchar *email);
 /* Sync folder items */
diff --git a/src/server/tests/test-connection.c b/src/server/tests/test-connection.c
index db543fa..811d9c7 100644
--- a/src/server/tests/test-connection.c
+++ b/src/server/tests/test-connection.c
@@ -120,24 +120,24 @@ con_test_autodiscover()
 	user_data->test_case = g_strdup ("postive case... \n");
 	g_print ("Testing %s \n", user_data->test_case);
 	user_data->positive_case = TRUE;
-	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, email, password);
+	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, email, password, NULL, NULL);
 
 	user_data = g_new0 (struct _cb_data, 1);
 	user_data->test_case =	g_strdup ("wrong password... \n");
 	/* It does respond properly with the url, Check it out */
 	user_data->positive_case = TRUE;
 	g_print ("Testing %s \n", user_data->test_case);
-	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, email, "wrongpassword");
+	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, email, "wrongpassword", NULL, NULL);
 
 	user_data = g_new0 (struct _cb_data, 1);
 	user_data->test_case = g_strdup ("email without domain ... \n");
 	g_print ("Testing %s \n", user_data->test_case);
-	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, "wronguseremail", password);
+	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, "wronguseremail", password, NULL, NULL);
 
 	user_data = g_new0 (struct _cb_data, 1);
 	user_data->test_case = g_strdup ("wrong email address and password... \n");
 	g_print ("Testing %s \n", user_data->test_case);
-	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, "godknows@donknow.com", "wrongpassword");
+	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, "godknows@donknow.com", "wrongpassword", NULL, NULL);
 
 	user_data->test_case = g_strdup ("wrong user name ... \n");
 	g_print ("Testing %s \n", user_data->test_case);
@@ -147,7 +147,7 @@ con_test_autodiscover()
 	user_data->test_case = g_strdup ("wrong user name ... \n");
 	g_print ("Testing %s \n", user_data->test_case);
 	user_data->quit = TRUE;
-	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, wrong_username, password);
+	e_ews_autodiscover_ws_url (autodiscover_cb, user_data, wrong_username, password, NULL, NULL);
 	g_free (wrong_username);
 }
 
