diff --git a/plugins/calendar-http/calendar-http.c b/plugins/calendar-http/calendar-http.c
index 7814ef5..f37773b 100644
--- a/plugins/calendar-http/calendar-http.c
+++ b/plugins/calendar-http/calendar-http.c
@@ -33,20 +33,54 @@ gboolean   e_calendar_http_check (EPlugin *epl, EConfigHookPageCheckData *data);
 GtkWidget * e_calendar_http_secure (EPlugin *epl, EConfigHookItemFactoryData *data);
 GtkWidget *e_calendar_http_auth (EPlugin *epl, EConfigHookItemFactoryData *data);
 
+/* replaces all '@' with '%40' in str; returns newly allocated string */
+static char *
+replace_at_sign (const char *str)
+{
+	char *res, *at;
+
+	if (!str)
+		return NULL;
+
+	res = g_strdup (str);
+	while (at = strchr (res, '@'), at) {
+		char *tmp = g_malloc0 (sizeof (char) * (1 + strlen (res) + 2));
+
+		strncpy (tmp, res, at - res);
+		strcat (tmp, "%40");
+		strcat (tmp, at + 1);
+
+		g_free (res);
+		res = tmp;
+	}
+
+	return res;
+}
+
 static gchar *
 print_uri_noproto (EUri *uri)
 {
-	gchar *uri_noproto;
+	gchar *uri_noproto, *user, *pass;
+
+	if (uri->user)
+		user = replace_at_sign (uri->user);
+	else
+		user = NULL;
+
+	if (uri->passwd)
+		pass = replace_at_sign (uri->passwd);
+	else
+		pass = NULL;
 
 	if (uri->port != 0)
 		uri_noproto = g_strdup_printf (
 			"%s%s%s%s%s%s%s:%d%s%s%s",
-			uri->user ? uri->user : "",
+			user ? user : "",
 			uri->authmech ? ";auth=" : "",
 			uri->authmech ? uri->authmech : "",
-			uri->passwd ? ":" : "",
-			uri->passwd ? uri->passwd : "",
-			uri->user ? "@" : "",
+			pass ? ":" : "",
+			pass ? pass : "",
+			user ? "@" : "",
 			uri->host ? uri->host : "",
 			uri->port,
 			uri->path ? uri->path : "",
@@ -55,16 +89,20 @@ print_uri_noproto (EUri *uri)
 	else
 		uri_noproto = g_strdup_printf (
 			"%s%s%s%s%s%s%s%s%s%s",
-			uri->user ? uri->user : "",
+			user ? user : "",
 			uri->authmech ? ";auth=" : "",
 			uri->authmech ? uri->authmech : "",
-			uri->passwd ? ":" : "",
-			uri->passwd ? uri->passwd : "",
-			uri->user ? "@" : "",
+			pass ? ":" : "",
+			pass ? pass : "",
+			user ? "@" : "",
 			uri->host ? uri->host : "",
 			uri->path ? uri->path : "",
 			uri->query ? "?" : "",
 			uri->query ? uri->query : "");
+
+	g_free (user);
+	g_free (pass);
+
 	return uri_noproto;
 }
 
@@ -85,6 +123,8 @@ url_changed (GtkEntry *entry, ESource *source)
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (secure_checkbox), TRUE);
 	}
 
+	g_free (uri->user);
+	uri->user = g_strdup (e_source_get_property (source, "username"));
 	relative_uri = print_uri_noproto (uri);
 	e_source_set_relative_uri (source, relative_uri);
 	g_free (relative_uri);
@@ -117,6 +157,11 @@ e_calendar_http_url (EPlugin *epl, EConfigHookItemFactoryData *data)
 		g_free (uri_text);
 		return hidden;
 	}
+	g_free (uri->user);
+	uri->user = NULL;
+
+	g_free (uri_text);
+	uri_text = e_uri_to_string (uri, FALSE);
 	e_uri_free (uri);
 
 	parent = data->parent;
@@ -341,6 +386,7 @@ static void
 username_changed (GtkEntry *entry, ESource *source)
 {
 	const gchar *username;
+	char *uri;
 
 	username = gtk_entry_get_text (GTK_ENTRY (entry));
 
@@ -351,6 +397,26 @@ username_changed (GtkEntry *entry, ESource *source)
 		e_source_set_property (source, "auth", NULL);
 		e_source_set_property (source, "username", NULL);
 	}
+
+	uri = e_source_get_uri (source);
+	if (uri != NULL) {
+		EUri *euri;
+		char *ruri;
+
+		if (username && !*username)
+			username = NULL;
+
+		euri = e_uri_new (uri);
+
+		g_free (euri->user);
+		euri->user = g_strdup (username);
+
+		ruri = print_uri_noproto (euri);
+		e_source_set_relative_uri (source, ruri);
+		e_uri_free (euri);
+		g_free (ruri);
+		g_free (uri);
+	}
 }
 
 GtkWidget *
