From d1aaf7fc9b9da32f04f84eef06bc0ee731e79223 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Mon, 17 Sep 2012 13:52:40 +0200
Subject: Fixed URL parsing/serializing.

Resolves: #1157,#1158

diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index e441c7c..8b0b540 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -751,7 +751,7 @@ void MainController::handleQuitRequest() {
 #define SERIALIZE_INT(option) result += boost::lexical_cast<std::string>(options.option); result += ",";
 #define SERIALIZE_STRING(option) result += Base64::encode(createByteArray(options.option)); result += ",";
 #define SERIALIZE_SAFE_STRING(option) result += safeByteArrayToString(Base64::encode(options.option)); result += ",";
-#define SERIALIZE_URL(option) SERIALIZE_STRING(option.getScheme()) SERIALIZE_STRING(option.getHost()) SERIALIZE_INT(option.getPort()) SERIALIZE_STRING(option.getPath())
+#define SERIALIZE_URL(option) SERIALIZE_STRING(option.toString())
 
 std::string MainController::serializeClientOptions(const ClientOptions& options) {
 	std::string result;
@@ -791,7 +791,7 @@ std::string MainController::serializeClientOptions(const ClientOptions& options)
 #define PARSE_INT(option, defaultValue) PARSE_INT_RAW(defaultValue); result.option = intVal;
 #define PARSE_STRING(option) PARSE_STRING_RAW; result.option = stringVal;
 #define PARSE_SAFE_STRING(option) PARSE_STRING_RAW; result.option = SafeString(createSafeByteArray(stringVal));
-#define PARSE_URL(option) {PARSE_STRING_RAW; std::string scheme = stringVal; PARSE_STRING_RAW; std::string host = stringVal; PARSE_INT_RAW(0); int port = intVal; PARSE_STRING_RAW; std::string path = stringVal; result.option = !scheme.empty() && !host.empty() ? URL(scheme, host, port, path) : URL();}
+#define PARSE_URL(option) {PARSE_STRING_RAW; result.option = URL::fromString(stringVal);}
 
 
 ClientOptions MainController::parseClientOptions(const std::string& optionString) {
diff --git a/Swift/QtUI/QtConnectionSettingsWindow.cpp b/Swift/QtUI/QtConnectionSettingsWindow.cpp
index 56ac65f..5bc2754 100644
--- a/Swift/QtUI/QtConnectionSettingsWindow.cpp
+++ b/Swift/QtUI/QtConnectionSettingsWindow.cpp
@@ -127,11 +127,12 @@ ClientOptions QtConnectionSettingsWindow::getOptions() {
 			options.boshURL = URL::fromString(Q2PSTRING(ui.bosh_uri->text()));
 			if (ui.bosh_manualProxy->isChecked()) {
 				std::string host = Q2PSTRING(ui.bosh_manualProxyHost->text());
-				int port = 80;
 				try {
-					port = boost::lexical_cast<int>(Q2PSTRING(ui.bosh_manualProxyPort->text()));
-				} catch (const boost::bad_lexical_cast&) {}
-				options.boshHTTPConnectProxyURL = URL("http", host, port, "");
+					int port = boost::lexical_cast<int>(Q2PSTRING(ui.bosh_manualProxyPort->text()));
+					options.boshHTTPConnectProxyURL = URL("http", host, port, "");
+				} catch (const boost::bad_lexical_cast&) {
+					options.boshHTTPConnectProxyURL = URL("http", host, "");
+				}
 			}
 		}
 	}
diff --git a/Swiften/Base/URL.cpp b/Swiften/Base/URL.cpp
index c36863f..28fe6d3 100644
--- a/Swiften/Base/URL.cpp
+++ b/Swiften/Base/URL.cpp
@@ -87,6 +87,28 @@ URL URL::fromString(const std::string& urlString) {
 	}
 }
 
+// FIXME: Escape non-ascii characters
+std::string URL::toString() const {
+	if (empty) {
+		return "";
+	}
+	std::string result = scheme + "://";
+	if (!user.empty()) {
+		result += user;
+		if (!password.empty()) {
+			result += ":" + password;
+		}
+		result += "@";
+	}
+	result += host;
+	if (port) {
+		result += ":";
+		result += boost::lexical_cast<std::string>(*port);
+	}
+	result += path;
+	return result;
+}
+
 // Disabling this code for now, since GCC4.5+boost1.42 (on ubuntu) seems to
 // result in a bug. Replacing it with naive code.
 #if 0
diff --git a/Swiften/Base/URL.h b/Swiften/Base/URL.h
index 00d58f1..75cf1a6 100644
--- a/Swiften/Base/URL.h
+++ b/Swiften/Base/URL.h
@@ -60,27 +60,7 @@ class SWIFTEN_API URL {
 			return path;
 		}
 
-		const std::string toString() const {
-			if (empty) {
-				return "";
-			}
-			std::string result = scheme + "://";
-			if (!user.empty()) {
-				result += user;
-				if (!password.empty()) {
-					result += ":" + password;
-				}
-				result += "@";
-			}
-			result += host;
-			if (port > 0) {
-				result += ":";
-				result += boost::lexical_cast<std::string>(port);
-			}
-			result += "/";
-			result += path;
-			return result;
-		}
+		std::string toString() const;
 
 		static int getPortOrDefaultPort(const URL& url);
 		static URL fromString(const std::string&);
diff --git a/Swiften/Base/UnitTest/URLTest.cpp b/Swiften/Base/UnitTest/URLTest.cpp
index 4de1d33..55c81f6 100644
--- a/Swiften/Base/UnitTest/URLTest.cpp
+++ b/Swiften/Base/UnitTest/URLTest.cpp
@@ -21,6 +21,8 @@ class URLTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST(testFromString_WithUserInfo);
 		CPPUNIT_TEST(testFromString_NonASCIIHost);
 		CPPUNIT_TEST(testFromString_NonASCIIPath);
+		CPPUNIT_TEST(testToString);
+		CPPUNIT_TEST(testToString_WithPort);
 		CPPUNIT_TEST_SUITE_END();
 
 	public:
@@ -79,6 +81,14 @@ class URLTest : public CppUnit::TestFixture {
 			
 			CPPUNIT_ASSERT_EQUAL(std::string("/baz/tron\xc3\xa7on/bam"), url.getPath());
 		}
+
+		void testToString() {
+			CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar/baz/bam"), URL("http", "foo.bar", "/baz/bam").toString());
+		}
+
+		void testToString_WithPort() {
+			CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar:1234/baz/bam"), URL("http", "foo.bar", 1234, "/baz/bam").toString());
+		}
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(URLTest);
-- 
cgit v0.10.2-6-g49f6