diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index a29e9aa..9ac2236 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1247,13 +1247,28 @@ auth_manager_authenticate (SoupAuthManager *manager, SoupMessage *msg,
 				     method == SOUP_METHOD_OPTIONS || \
 				     method == SOUP_METHOD_PROPFIND)
 
+static gboolean
+uri_has_non_ascii (const char *uri)
+{
+	const unsigned char *s = (const unsigned char *)uri;
+
+	while (*s) {
+		if (*s > 0x7f)
+			return TRUE;
+		s++;
+	}
+	return FALSE;
+}
+
 static void
 redirect_handler (SoupMessage *msg, gpointer user_data)
 {
 	SoupMessageQueueItem *item = user_data;
 	SoupSession *session = item->session;
 	const char *new_loc;
+	char *new_loc_encoded = NULL;
 	SoupURI *new_uri;
+	const unsigned char *s;
 
 	new_loc = soup_message_headers_get_one (msg->response_headers,
 						"Location");
@@ -1307,6 +1322,29 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
 		return;
 	}
 
+	/* Location is supposed to be an URI, but some sites
+	 * have non-ASCII octets in the URI. Following code
+	 * percent escapes non-ASCII (0x80 - 0xFF) octets only.
+	 * This is what Firefox also does.
+	 */
+	if (uri_has_non_ascii (new_loc)) {
+		GString *str;
+		const unsigned char *s = (const unsigned char *)new_loc;
+
+		str = g_string_sized_new (128);
+
+		while (*s) {
+			if (*s > 0x7f)
+				g_string_append_printf (str, "%%%02X", (int)*s++);
+			else
+				g_string_append_c (str, *s++);
+		}
+
+		new_loc_encoded = str->str;
+		new_loc = new_loc_encoded;
+		g_string_free (str, FALSE);
+	}
+
 	/* Location is supposed to be an absolute URI, but some sites
 	 * are lame, so we use soup_uri_new_with_base().
 	 */
@@ -1317,11 +1355,13 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
 		soup_message_set_status_full (msg,
 					      SOUP_STATUS_MALFORMED,
 					      "Invalid Redirect URL");
+		g_free (new_loc_encoded);
 		return;
 	}
 
 	soup_message_set_uri (msg, new_uri);
 	soup_uri_free (new_uri);
+	g_free (new_loc_encoded);
 
 	soup_session_requeue_message (session, msg);
 }
