Explorar o código

2010-09-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Moved URI parser code to uri.h, uri.cc to provide fast URI parser
	without Request object initialization.
	* src/Makefile.am
	* src/Request.cc
	* src/uri.cc
	* src/uri.h
	* test/Makefile.am
	* test/RequestTest.cc
	* test/UriTest.cc
Tatsuhiro Tsujikawa %!s(int64=15) %!d(string=hai) anos
pai
achega
ec3bd81486
Modificáronse 10 ficheiros con 750 adicións e 479 borrados
  1. 12 0
      ChangeLog
  2. 2 1
      src/Makefile.am
  3. 15 13
      src/Makefile.in
  4. 15 152
      src/Request.cc
  5. 207 0
      src/uri.cc
  6. 71 0
      src/uri.h
  7. 2 1
      test/Makefile.am
  8. 7 5
      test/Makefile.in
  9. 30 307
      test/RequestTest.cc
  10. 389 0
      test/UriTest.cc

+ 12 - 0
ChangeLog

@@ -1,3 +1,15 @@
+2010-09-11  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Moved URI parser code to uri.h, uri.cc to provide fast URI parser
+	without Request object initialization.
+	* src/Makefile.am
+	* src/Request.cc
+	* src/uri.cc
+	* src/uri.h
+	* test/Makefile.am
+	* test/RequestTest.cc
+	* test/UriTest.cc
+
 2010-09-10  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Store last error of removed download result so that it can be used

+ 2 - 1
src/Makefile.am

@@ -211,7 +211,8 @@ SRCS =  Socket.h\
 	SinkStreamFilter.cc SinkStreamFilter.h\
 	GZipDecodingStreamFilter.cc GZipDecodingStreamFilter.h\
 	ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h\
-	NullSinkStreamFilter.cc NullSinkStreamFilter.h
+	NullSinkStreamFilter.cc NullSinkStreamFilter.h\
+	uri.cc uri.h
 
 if ENABLE_XML_RPC
 SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\

+ 15 - 13
src/Makefile.in

@@ -446,7 +446,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	StreamFilter.h SinkStreamFilter.cc SinkStreamFilter.h \
 	GZipDecodingStreamFilter.cc GZipDecodingStreamFilter.h \
 	ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h \
-	NullSinkStreamFilter.cc NullSinkStreamFilter.h \
+	NullSinkStreamFilter.cc NullSinkStreamFilter.h uri.cc uri.h \
 	XmlRpcRequestParserController.cc \
 	XmlRpcRequestParserController.h \
 	XmlRpcRequestParserStateMachine.cc \
@@ -890,7 +890,7 @@ am__objects_32 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
 	StreamFilter.$(OBJEXT) SinkStreamFilter.$(OBJEXT) \
 	GZipDecodingStreamFilter.$(OBJEXT) \
 	ChunkedDecodingStreamFilter.$(OBJEXT) \
-	NullSinkStreamFilter.$(OBJEXT) $(am__objects_1) \
+	NullSinkStreamFilter.$(OBJEXT) uri.$(OBJEXT) $(am__objects_1) \
 	$(am__objects_2) $(am__objects_3) $(am__objects_4) \
 	$(am__objects_5) $(am__objects_6) $(am__objects_7) \
 	$(am__objects_8) $(am__objects_9) $(am__objects_10) \
@@ -1238,17 +1238,18 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
 	StreamFilter.h SinkStreamFilter.cc SinkStreamFilter.h \
 	GZipDecodingStreamFilter.cc GZipDecodingStreamFilter.h \
 	ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h \
-	NullSinkStreamFilter.cc NullSinkStreamFilter.h $(am__append_1) \
-	$(am__append_2) $(am__append_3) $(am__append_4) \
-	$(am__append_5) $(am__append_6) $(am__append_7) \
-	$(am__append_8) $(am__append_9) $(am__append_10) \
-	$(am__append_11) $(am__append_12) $(am__append_13) \
-	$(am__append_14) $(am__append_15) $(am__append_16) \
-	$(am__append_17) $(am__append_18) $(am__append_19) \
-	$(am__append_20) $(am__append_21) $(am__append_22) \
-	$(am__append_23) $(am__append_24) $(am__append_25) \
-	$(am__append_26) $(am__append_27) $(am__append_28) \
-	$(am__append_29) $(am__append_30) $(am__append_31)
+	NullSinkStreamFilter.cc NullSinkStreamFilter.h uri.cc uri.h \
+	$(am__append_1) $(am__append_2) $(am__append_3) \
+	$(am__append_4) $(am__append_5) $(am__append_6) \
+	$(am__append_7) $(am__append_8) $(am__append_9) \
+	$(am__append_10) $(am__append_11) $(am__append_12) \
+	$(am__append_13) $(am__append_14) $(am__append_15) \
+	$(am__append_16) $(am__append_17) $(am__append_18) \
+	$(am__append_19) $(am__append_20) $(am__append_21) \
+	$(am__append_22) $(am__append_23) $(am__append_24) \
+	$(am__append_25) $(am__append_26) $(am__append_27) \
+	$(am__append_28) $(am__append_29) $(am__append_30) \
+	$(am__append_31)
 noinst_LIBRARIES = libaria2c.a
 libaria2c_a_SOURCES = $(SRCS)
 aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@@ -1682,6 +1683,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefs.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strptime.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timegm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uri.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version_usage.Po@am__quote@
 

+ 15 - 152
src/Request.cc

@@ -41,6 +41,7 @@
 #include "StringFormat.h"
 #include "A2STR.h"
 #include "a2functional.h"
+#include "uri.h"
 
 namespace aria2 {
 
@@ -147,161 +148,23 @@ bool Request::redirectUri(const std::string& uri) {
 }
 
 bool Request::parseUri(const std::string& srcUri) {
-  const std::string uri = percentEncode(removeFragment(srcUri));
-  currentUri_ = uri;
-  host_ = A2STR::NIL;
-  port_ = 0;
-  dir_ = A2STR::NIL;
-  file_ = A2STR::NIL;
-  query_ = A2STR::NIL;
-  username_ = A2STR::NIL;
-  password_ = A2STR::NIL;
-  hasPassword_ = false;
-  ipv6LiteralAddress_ = false;
-
-  // http://user:password@aria2.sourceforge.net:80/dir/file?query
-  //        |            ||                    || |   |    |
-  //        |            ||             hostLast| |   |    |
-  //        |            ||              portFirst|   |    |
-  //    authorityFirst   ||             authorityLast |    |
-  //                     ||                       |   |    |
-  //                   userInfoLast               |   |    |
-  //                      |                       |   |    |
-  //                     hostPortFirst            |   |    |
-  //                                              |   |    |
-  //                                       dirFirst dirLast|
-  //                                                       |
-  //                                                queryFirst
-
-  // find query part
-  std::string::const_iterator queryFirst = uri.begin();
-  for(; queryFirst != uri.end(); ++queryFirst) {
-    if(*queryFirst == '?') break;
-  }
-  query_ = std::string(queryFirst, uri.end());
-  // find protocol
-  std::string::size_type protocolOffset = uri.find("://");
-  if(protocolOffset == std::string::npos) return false;
-  protocol_ = std::string(uri.begin(), uri.begin()+protocolOffset);
-  uint16_t defPort;
-  if((defPort = FeatureConfig::getInstance()->getDefaultPort(protocol_)) == 0) {
-    return false;
-  }
-  // find authority
-  std::string::const_iterator authorityFirst = uri.begin()+protocolOffset+3;
-  std::string::const_iterator authorityLast = authorityFirst;
-  for(; authorityLast != queryFirst; ++authorityLast) {
-    if(*authorityLast == '/') break;
-  }
-  if(authorityFirst == authorityLast) {
-    // No authority found
-    return false;
-  }
-  // find userinfo(username and password) in authority if they exist
-  std::string::const_iterator userInfoLast = authorityLast;
-  std::string::const_iterator hostPortFirst = authorityFirst;
-  for(; userInfoLast != authorityFirst-1; --userInfoLast) {
-    if(*userInfoLast == '@') {
-      hostPortFirst = userInfoLast;
-      ++hostPortFirst;
-      std::string::const_iterator userLast = authorityFirst;
-      for(; userLast != userInfoLast; ++userLast) {
-        if(*userLast == ':') {
-          password_ = util::percentDecode(std::string(userLast+1,userInfoLast));
-          hasPassword_ = true;
-          break;
-        }
-      }
-      username_ = util::percentDecode(std::string(authorityFirst, userLast));
-      break;
-    }
-  }
-  std::string::const_iterator hostLast = hostPortFirst;
-  std::string::const_iterator portFirst = authorityLast;
-  if(*hostPortFirst == '[') {
-    // Detected IPv6 literal address in square brackets
-    for(; hostLast != authorityLast; ++hostLast) {
-      if(*hostLast == ']') {
-        ++hostLast;
-        if(hostLast == authorityLast) {
-          ipv6LiteralAddress_ = true;
-        } else {
-          if(*hostLast == ':') {
-            portFirst = hostLast;
-            ++portFirst;
-            ipv6LiteralAddress_ = true;
-          }
-        }
-        break;
-      }
-    }
-    if(!ipv6LiteralAddress_) {
-      return false;
-    }
+  currentUri_ = percentEncode(removeFragment(srcUri));
+  uri::UriStruct us;
+  if(uri::parse(us, currentUri_)) {
+    protocol_.swap(us.protocol);
+    host_.swap(us.host);
+    port_ = us.port;
+    dir_.swap(us.dir);
+    file_.swap(us.file);
+    query_.swap(us.query);
+    username_.swap(us.username);
+    password_.swap(us.password);
+    hasPassword_ = us.hasPassword;
+    ipv6LiteralAddress_ = us.ipv6LiteralAddress;
+    return true;
   } else {
-    for(; hostLast != authorityLast; ++hostLast) {
-      if(*hostLast == ':') {
-        portFirst = hostLast;
-        ++portFirst;
-        break;
-      }
-    }
-  }
-  if(hostPortFirst == hostLast) {
-    // No host
     return false;
   }
-  if(portFirst == authorityLast) {
-    // If port is not specified, then we set it to default port of
-    // its protocol..
-    port_ = defPort;
-  } else {
-    uint32_t tempPort;
-    if(util::parseUIntNoThrow(tempPort, std::string(portFirst, authorityLast))){
-      if(65535 < tempPort) {
-        return false;
-      }
-      port_ = tempPort;      
-    } else {
-      return false;
-    }
-  }
-  if(ipv6LiteralAddress_) {
-    host_ = std::string(hostPortFirst+1, hostLast-1);
-  } else {
-    host_ = std::string(hostPortFirst, hostLast);
-  }
-  // find directory and file part
-  std::string::const_iterator dirLast = authorityLast;
-  for(std::string::const_iterator i = authorityLast;
-      i != queryFirst; ++i) {
-    if(*i == '/') {
-      dirLast = i;
-    }
-  }
-  if(dirLast != queryFirst) {
-    file_ = std::string(dirLast+1, queryFirst);
-  }
-  // Erase duplicated slashes.
-  std::string::const_iterator dirFirst = authorityLast;
-  for(; dirFirst != dirLast; ++dirFirst) {
-    if(*dirFirst != '/') {
-      --dirFirst;
-      break;
-    }
-  }
-  for(; dirLast != dirFirst; --dirLast) {
-    if(*dirLast != '/') {
-      ++dirLast;
-      break;
-    }
-  }
-  if(dirFirst == dirLast) {
-    dir_ = A2STR::SLASH_C;
-  } else {
-    dir_ = std::string(dirFirst, dirLast);
-  }
-  return true;
 }
 
 void Request::resetRedirectCount()

+ 207 - 0
src/uri.cc

@@ -0,0 +1,207 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2010 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "uri.h"
+#include "A2STR.h"
+#include "FeatureConfig.h"
+#include "util.h"
+
+namespace aria2 {
+
+namespace uri {
+
+bool parse(UriStruct& result, const std::string& uri)
+{
+  // http://user:password@aria2.sourceforge.net:80/dir/file?query#fragment
+  //        |            ||                    || |   |    |     |
+  //        |            ||             hostLast| |   |    |     |
+  //        |            ||              portFirst|   |    |     |
+  //    authorityFirst   ||             authorityLast |    |     |
+  //                     ||                       |   |    |     |
+  //                   userInfoLast               |   |    |     |
+  //                      |                       |   |    |     |
+  //                     hostPortFirst            |   |    |     |
+  //                                              |   |    |     |
+  //                                       dirFirst dirLast|     |
+  //                                                       |     |
+  //                                                queryFirst fragmentFirst
+
+  // find fragment part
+  std::string::const_iterator fragmentFirst = uri.begin();
+  for(; fragmentFirst != uri.end(); ++fragmentFirst) {
+    if(*fragmentFirst == '#') break;
+  }
+  // find query part
+  std::string::const_iterator queryFirst = uri.begin();
+  for(; queryFirst != fragmentFirst; ++queryFirst) {
+    if(*queryFirst == '?') break;
+  }
+  result.query = std::string(queryFirst, fragmentFirst);
+  // find protocol
+  std::string::size_type protocolOffset = uri.find("://");
+  if(protocolOffset == std::string::npos) return false;
+  result.protocol = std::string(uri.begin(), uri.begin()+protocolOffset);
+  uint16_t defPort;
+  if((defPort = FeatureConfig::getInstance()->
+      getDefaultPort(result.protocol)) == 0) {
+    return false;
+  }
+  // find authority
+  std::string::const_iterator authorityFirst = uri.begin()+protocolOffset+3;
+  std::string::const_iterator authorityLast = authorityFirst;
+  for(; authorityLast != queryFirst; ++authorityLast) {
+    if(*authorityLast == '/') break;
+  }
+  if(authorityFirst == authorityLast) {
+    // No authority found
+    return false;
+  }
+  // find userinfo(username and password) in authority if they exist
+  result.username = A2STR::NIL;
+  result.password = A2STR::NIL;
+  result.hasPassword = false;
+  std::string::const_iterator userInfoLast = authorityLast;
+  std::string::const_iterator hostPortFirst = authorityFirst;
+  for(; userInfoLast != authorityFirst-1; --userInfoLast) {
+    if(*userInfoLast == '@') {
+      hostPortFirst = userInfoLast;
+      ++hostPortFirst;
+      std::string::const_iterator userLast = authorityFirst;
+      for(; userLast != userInfoLast; ++userLast) {
+        if(*userLast == ':') {
+          result.password =
+            util::percentDecode(std::string(userLast+1,userInfoLast));
+          result.hasPassword = true;
+          break;
+        }
+      }
+      result.username =
+        util::percentDecode(std::string(authorityFirst, userLast));
+      break;
+    }
+  }
+  std::string::const_iterator hostLast = hostPortFirst;
+  std::string::const_iterator portFirst = authorityLast;
+  result.ipv6LiteralAddress = false;
+  if(*hostPortFirst == '[') {
+    // Detected IPv6 literal address in square brackets
+    for(; hostLast != authorityLast; ++hostLast) {
+      if(*hostLast == ']') {
+        ++hostLast;
+        if(hostLast == authorityLast) {
+          result.ipv6LiteralAddress = true;
+        } else {
+          if(*hostLast == ':') {
+            portFirst = hostLast;
+            ++portFirst;
+            result.ipv6LiteralAddress = true;
+          }
+        }
+        break;
+      }
+    }
+    if(!result.ipv6LiteralAddress) {
+      return false;
+    }
+  } else {
+    for(; hostLast != authorityLast; ++hostLast) {
+      if(*hostLast == ':') {
+        portFirst = hostLast;
+        ++portFirst;
+        break;
+      }
+    }
+  }
+  if(hostPortFirst == hostLast) {
+    // No host
+    return false;
+  }
+  if(portFirst == authorityLast) {
+    // If port is not specified, then we set it to default port of
+    // its protocol..
+    result.port = defPort;
+  } else {
+    uint32_t tempPort;
+    if(util::parseUIntNoThrow(tempPort, std::string(portFirst, authorityLast))){
+      if(65535 < tempPort) {
+        return false;
+      }
+      result.port = tempPort;      
+    } else {
+      return false;
+    }
+  }
+  if(result.ipv6LiteralAddress) {
+    result.host = std::string(hostPortFirst+1, hostLast-1);
+  } else {
+    result.host = std::string(hostPortFirst, hostLast);
+  }
+  // find directory and file part
+  std::string::const_iterator dirLast = authorityLast;
+  for(std::string::const_iterator i = authorityLast;
+      i != queryFirst; ++i) {
+    if(*i == '/') {
+      dirLast = i;
+    }
+  }
+  if(dirLast == queryFirst) {
+    result.file = A2STR::NIL;
+  } else {
+    result.file = std::string(dirLast+1, queryFirst);
+  }
+  // Erase duplicated slashes.
+  std::string::const_iterator dirFirst = authorityLast;
+  for(; dirFirst != dirLast; ++dirFirst) {
+    if(*dirFirst != '/') {
+      --dirFirst;
+      break;
+    }
+  }
+  for(; dirLast != dirFirst; --dirLast) {
+    if(*dirLast != '/') {
+      ++dirLast;
+      break;
+    }
+  }
+  if(dirFirst == dirLast) {
+    result.dir = A2STR::SLASH_C;
+  } else {
+    result.dir = std::string(dirFirst, dirLast);
+  }
+  return true;
+}
+
+} // namespace uri
+
+} // namespace aria2

+ 71 - 0
src/uri.h

@@ -0,0 +1,71 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2010 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef D_URI_H
+#define D_URI_H
+
+#include "common.h"
+
+#include <string>
+#include "A2STR.h"
+
+namespace aria2 {
+
+namespace uri {
+
+struct UriStruct {
+  std::string protocol;
+  std::string host;
+  uint16_t port;
+  std::string dir;
+  std::string file;
+  std::string query;
+  std::string username;
+  std::string password;
+  bool hasPassword;
+  bool ipv6LiteralAddress;
+
+  UriStruct():port(0), hasPassword(false), ipv6LiteralAddress(false) {}
+};
+
+// Splits URI uri into components and stores them into result.  On
+// success returns true. Otherwise returns false and result is
+// undefined.
+bool parse(UriStruct& result, const std::string& uri);
+
+} // namespace uri
+
+} // namespace aria2
+
+#endif // D_URI_H

+ 2 - 1
test/Makefile.am

@@ -74,7 +74,8 @@ aria2c_SOURCES = AllTest.cc\
 	SessionSerializerTest.cc\
 	ValueBaseTest.cc\
 	ChunkedDecodingStreamFilterTest.cc\
-	GZipDecodingStreamFilterTest.cc
+	GZipDecodingStreamFilterTest.cc\
+	UriTest.cc
 
 if ENABLE_XML_RPC
 aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\

+ 7 - 5
test/Makefile.in

@@ -214,7 +214,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 	a2algoTest.cc bitfieldTest.cc DownloadContextTest.cc \
 	SessionSerializerTest.cc ValueBaseTest.cc \
 	ChunkedDecodingStreamFilterTest.cc \
-	GZipDecodingStreamFilterTest.cc \
+	GZipDecodingStreamFilterTest.cc UriTest.cc \
 	XmlRpcRequestParserControllerTest.cc \
 	XmlRpcRequestProcessorTest.cc XmlRpcMethodTest.cc \
 	FallocFileAllocationIteratorTest.cc GZipDecoderTest.cc \
@@ -408,9 +408,10 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
 	DownloadContextTest.$(OBJEXT) SessionSerializerTest.$(OBJEXT) \
 	ValueBaseTest.$(OBJEXT) \
 	ChunkedDecodingStreamFilterTest.$(OBJEXT) \
-	GZipDecodingStreamFilterTest.$(OBJEXT) $(am__objects_1) \
-	$(am__objects_2) $(am__objects_3) $(am__objects_4) \
-	$(am__objects_5) $(am__objects_6) $(am__objects_7)
+	GZipDecodingStreamFilterTest.$(OBJEXT) UriTest.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5) $(am__objects_6) \
+	$(am__objects_7)
 aria2c_OBJECTS = $(am_aria2c_OBJECTS)
 am__DEPENDENCIES_1 =
 aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@@ -645,7 +646,7 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
 	a2algoTest.cc bitfieldTest.cc DownloadContextTest.cc \
 	SessionSerializerTest.cc ValueBaseTest.cc \
 	ChunkedDecodingStreamFilterTest.cc \
-	GZipDecodingStreamFilterTest.cc $(am__append_1) \
+	GZipDecodingStreamFilterTest.cc UriTest.cc $(am__append_1) \
 	$(am__append_2) $(am__append_3) $(am__append_4) \
 	$(am__append_5) $(am__append_6) $(am__append_7)
 
@@ -900,6 +901,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataRequestTrackerTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessageTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParserTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ValueBaseTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XORCloserTest.Po@am__quote@

+ 30 - 307
test/RequestTest.cc

@@ -5,6 +5,7 @@
 #include "Netrc.h"
 #include "DefaultAuthResolver.h"
 #include "NetrcAuthResolver.h"
+#include "uri.h"
 
 namespace aria2 {
 
@@ -13,29 +14,9 @@ class RequestTest:public CppUnit::TestFixture {
   CPPUNIT_TEST_SUITE(RequestTest);
   CPPUNIT_TEST(testSetUri1);
   CPPUNIT_TEST(testSetUri2);
-  CPPUNIT_TEST(testSetUri3);
-  CPPUNIT_TEST(testSetUri4);
-  CPPUNIT_TEST(testSetUri5);
-  CPPUNIT_TEST(testSetUri6);
   CPPUNIT_TEST(testSetUri7);
-  CPPUNIT_TEST(testSetUri8);
-  CPPUNIT_TEST(testSetUri9);
-  CPPUNIT_TEST(testSetUri10);
-  CPPUNIT_TEST(testSetUri11);
-  CPPUNIT_TEST(testSetUri12);
-  CPPUNIT_TEST(testSetUri13);
-  CPPUNIT_TEST(testSetUri14);
-  CPPUNIT_TEST(testSetUri15);
-  CPPUNIT_TEST(testSetUri16);
   CPPUNIT_TEST(testSetUri17);
-  CPPUNIT_TEST(testSetUri18);
-  CPPUNIT_TEST(testSetUri19);
-  CPPUNIT_TEST(testSetUri20);
-  CPPUNIT_TEST(testSetUri_username);
-  CPPUNIT_TEST(testSetUri_usernamePassword);
-  CPPUNIT_TEST(testSetUri_zeroUsername);
   CPPUNIT_TEST(testSetUri_supportsPersistentConnection);
-  CPPUNIT_TEST(testSetUri_ipv6);
   CPPUNIT_TEST(testRedirectUri);
   CPPUNIT_TEST(testRedirectUri2);
   CPPUNIT_TEST(testRedirectUri_supportsPersistentConnection);
@@ -49,29 +30,9 @@ class RequestTest:public CppUnit::TestFixture {
 public:
   void testSetUri1();
   void testSetUri2();
-  void testSetUri3();
-  void testSetUri4();
-  void testSetUri5();
-  void testSetUri6();
   void testSetUri7();
-  void testSetUri8();
-  void testSetUri9();
-  void testSetUri10();
-  void testSetUri11();
-  void testSetUri12();
-  void testSetUri13();
-  void testSetUri14();
-  void testSetUri15();
-  void testSetUri16();
   void testSetUri17();
-  void testSetUri18();
-  void testSetUri19();
-  void testSetUri20();
-  void testSetUri_username();
-  void testSetUri_usernamePassword();
-  void testSetUri_zeroUsername();
   void testSetUri_supportsPersistentConnection();
-  void testSetUri_ipv6();
   void testRedirectUri();
   void testRedirectUri2();
   void testRedirectUri_supportsPersistentConnection();
@@ -90,8 +51,10 @@ void RequestTest::testSetUri1() {
   bool v = req.setUri("http://aria.rednoah.com/");
 
   CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/"), req.getUri());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/"), req.getCurrentUri());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/"),
+                       req.getUri());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/"),
+                       req.getCurrentUri());
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPreviousUri());
   CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
   CPPUNIT_ASSERT_EQUAL((uint16_t)80, req.getPort());
@@ -112,7 +75,8 @@ void RequestTest::testSetUri2() {
   CPPUNIT_ASSERT(v);
 
   // referer is unchaged
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080"), req.getReferer());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080"),
+                       req.getReferer());
   // previousUri must equal to referer;
   CPPUNIT_ASSERT_EQUAL(req.getReferer(), req.getPreviousUri());
   CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
@@ -123,58 +87,6 @@ void RequestTest::testSetUri2() {
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
 }
 
-void RequestTest::testSetUri3() {
-  Request req;
-  bool v = req.setUri("http://aria.rednoah.com/aria2/index.html");
-
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)80, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/aria2"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
-void RequestTest::testSetUri4() {
-  Request req;
-  bool v = req.setUri("http://aria.rednoah.com/aria2/aria3/index.html");
-
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)80, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/aria2/aria3"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
-void RequestTest::testSetUri5() {
-  Request req;
-  bool v = req.setUri("http://aria.rednoah.com/aria2/aria3/");
-
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)80, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/aria2/aria3"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
-void RequestTest::testSetUri6() {
-  Request req;
-  bool v = req.setUri("http://aria.rednoah.com/aria2/aria3");
-
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)80, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/aria2"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria3"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
 void RequestTest::testSetUri7() {
   Request req;
   bool v = req.setUri("http://");
@@ -182,111 +94,18 @@ void RequestTest::testSetUri7() {
   CPPUNIT_ASSERT(!v);
 }
 
-void RequestTest::testSetUri8() {
-  Request req;
-  bool v = req.setUri("http:/aria.rednoah.com");
-
-  CPPUNIT_ASSERT(!v);
-}
-
-void RequestTest::testSetUri9() {
-  Request req;
-  bool v = req.setUri("h");
-
-  CPPUNIT_ASSERT(!v);
-}
-
-void RequestTest::testSetUri10() {
-  Request req;
-  bool v = req.setUri("");
-
-  CPPUNIT_ASSERT(!v);
-}
-
-void RequestTest::testSetUri11() {
-  Request req;
-  bool v = req.setUri("http://host?query/");
-
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("?query/"), req.getQuery());
-}
-
-void RequestTest::testSetUri12() {
-  Request req;
-  bool v = req.setUri("http://host?query");
-  
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("?query"), req.getQuery());
-}
-
-void RequestTest::testSetUri13() {
-  Request req;
-  bool v = req.setUri("http://host/?query");
-  
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("?query"), req.getQuery());
-}
-
-void RequestTest::testSetUri14() {
-  Request req;
-  bool v = req.setUri("http://host:8080/abc?query");
-  
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)8080, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("abc"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("?query"), req.getQuery());
-}
-
-void RequestTest::testSetUri15()
-{
-  Request req;
-  // 2 slashes after host name and dir
-  bool v = req.setUri("http://host//dir1/dir2//file");
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/dir1/dir2"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
-void RequestTest::testSetUri16()
-{
-  Request req;
-  // 2 slashes before file
-  bool v = req.setUri("http://host//file");
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
-}
-
 void RequestTest::testSetUri17()
 {
   Request req;
-  bool v = req.setUri("http://host:80/file<with%2 %20space/file with space;param%?a=/?");
+  bool v = req.setUri("http://host:80/file<with%2 %20space/"
+                      "file with space;param%?a=/?");
   CPPUNIT_ASSERT(v);
   CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
   CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/file%3Cwith%252%20%20space"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file%20with%20space;param%25"), req.getFile());
+  CPPUNIT_ASSERT_EQUAL(std::string("/file%3Cwith%252%20%20space"),
+                       req.getDir());
+  CPPUNIT_ASSERT_EQUAL(std::string("file%20with%20space;param%25"),
+                       req.getFile());
   CPPUNIT_ASSERT_EQUAL(std::string("?a=/?"), req.getQuery());
   CPPUNIT_ASSERT_EQUAL(std::string("http://host:80/file%3Cwith%252%20%20space"
                                    "/file%20with%20space;param%25?a=/?"),
@@ -296,34 +115,8 @@ void RequestTest::testSetUri17()
                        req.getUri());
 }
 
-void RequestTest::testSetUri18() {
-  Request req;
-  bool v = req.setUri("http://1/");
-
-  CPPUNIT_ASSERT(v);
-}
-
-void RequestTest::testSetUri19() {
-  Request req;
-  // No host
-  bool v = req.setUri("http://user@");
-
-  CPPUNIT_ASSERT(!v);
-}
-
-void RequestTest::testSetUri20() {
-  Request req;
-  bool v;
-  // Invalid port
-  v = req.setUri("http://localhost:65536");
-  CPPUNIT_ASSERT(!v);
-  v = req.setUri("http://localhost:65535");
-  CPPUNIT_ASSERT(v);
-  v = req.setUri("http://localhost:-80");
-  CPPUNIT_ASSERT(!v);
-}
-
-void RequestTest::testRedirectUri() {
+void RequestTest::testRedirectUri()
+{
   Request req;
   req.supportsPersistentConnection(false);
   req.setUri("http://aria.rednoah.com:8080/aria2/index.html");
@@ -369,7 +162,8 @@ void RequestTest::testRedirectUri() {
                        req.getCurrentUri());
 }
 
-void RequestTest::testRedirectUri2() {
+void RequestTest::testRedirectUri2()
+{
   Request req;
   req.setUri("http://aria.rednoah.com/download.html");
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPreviousUri());
@@ -393,7 +187,8 @@ void RequestTest::testRedirectUri2() {
                        req.getPreviousUri());
 }
   
-void RequestTest::testResetUri() {
+void RequestTest::testResetUri()
+{
   Request req;
   req.setUri("http://aria.rednoah.com:8080/aria2/index.html");
   req.setReferer("http://aria.rednoah.com:8080/");
@@ -402,12 +197,16 @@ void RequestTest::testResetUri() {
   bool v3 = req.resetUri();
   CPPUNIT_ASSERT(v3);
   // currentUri must equal to uri
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080/aria2/index.html"), req.getUri());
+  CPPUNIT_ASSERT_EQUAL
+    (std::string("http://aria.rednoah.com:8080/aria2/index.html"),
+     req.getUri());
   CPPUNIT_ASSERT_EQUAL(req.getUri(), req.getCurrentUri());
   // previousUri must equal to referer
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080/"), req.getPreviousUri());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080/"),
+                       req.getPreviousUri());
   // referer is unchanged
-  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080/"), req.getReferer());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com:8080/"),
+                       req.getReferer());
   CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
   CPPUNIT_ASSERT_EQUAL((uint16_t)8080, req.getPort());
   CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), req.getHost());
@@ -416,7 +215,8 @@ void RequestTest::testResetUri() {
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
 }
 
-void RequestTest::testInnerLink() {
+void RequestTest::testInnerLink()
+{
   Request req;
   bool v = req.setUri("http://aria.rednoah.com/index.html#download");
   CPPUNIT_ASSERT(v);
@@ -429,76 +229,14 @@ void RequestTest::testInnerLink() {
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
 }
 
-void RequestTest::testInnerLinkInReferer() {
+void RequestTest::testInnerLinkInReferer()
+{
   Request req;
   req.setReferer("http://aria.rednoah.com/home.html#top");
   CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/home.html"),
                        req.getReferer());
 }
 
-void RequestTest::testSetUri_zeroUsername()
-{
-  Request req;
-  CPPUNIT_ASSERT(req.setUri("ftp://@localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)21, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/download"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPassword());
-
-  CPPUNIT_ASSERT(req.setUri("ftp://:@localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)21, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/download"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPassword());
-
-  CPPUNIT_ASSERT(req.setUri("ftp://:pass@localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)21, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/download"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string("pass"), req.getPassword());
-
-}
-
-void RequestTest::testSetUri_username()
-{
-  Request req;
-  CPPUNIT_ASSERT(req.setUri("ftp://aria2@user@localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)21, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/download"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2@user"), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPassword());
-}
-
-void RequestTest::testSetUri_usernamePassword()
-{
-  Request req;
-  CPPUNIT_ASSERT(req.setUri("ftp://aria2@user%40:aria2@pass%40@localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)21, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/download"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2@user@"), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2@pass@"), req.getPassword());
-
-  // make sure that after new uri is set, username and password are updated.
-  CPPUNIT_ASSERT(req.setUri("ftp://localhost/download/aria2-1.0.0.tar.bz2"));
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getUsername());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), req.getPassword());
-}
-
 void RequestTest::testSetUri_supportsPersistentConnection()
 {
   Request req;
@@ -529,21 +267,6 @@ void RequestTest::testRedirectUri_supportsPersistentConnection()
   CPPUNIT_ASSERT(req.supportsPersistentConnection());
 }
 
-void RequestTest::testSetUri_ipv6()
-{
-  Request req;
-  CPPUNIT_ASSERT(!req.setUri("http://[::1"));
-  CPPUNIT_ASSERT(req.setUri("http://[::1]"));
-  CPPUNIT_ASSERT_EQUAL(std::string("::1"), req.getHost());
-
-  CPPUNIT_ASSERT(req.setUri("http://[::1]:8000/dir/file"));
-  CPPUNIT_ASSERT_EQUAL(std::string("::1"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL((uint16_t)8000, req.getPort());
-  CPPUNIT_ASSERT_EQUAL(std::string("/dir"), req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file"), req.getFile());
-  CPPUNIT_ASSERT(req.isIPv6LiteralAddress());
-}
-
 void RequestTest::testGetURIHost()
 {
   Request req;

+ 389 - 0
test/UriTest.cc

@@ -0,0 +1,389 @@
+#include "uri.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace aria2 {
+
+namespace uri {
+
+class UriTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(UriTest);
+  CPPUNIT_TEST(testSetUri1);
+  CPPUNIT_TEST(testSetUri2);
+  CPPUNIT_TEST(testSetUri3);
+  CPPUNIT_TEST(testSetUri4);
+  CPPUNIT_TEST(testSetUri5);
+  CPPUNIT_TEST(testSetUri6);
+  CPPUNIT_TEST(testSetUri7);
+  CPPUNIT_TEST(testSetUri8);
+  CPPUNIT_TEST(testSetUri9);
+  CPPUNIT_TEST(testSetUri10);
+  CPPUNIT_TEST(testSetUri11);
+  CPPUNIT_TEST(testSetUri12);
+  CPPUNIT_TEST(testSetUri13);
+  CPPUNIT_TEST(testSetUri14);
+  CPPUNIT_TEST(testSetUri15);
+  CPPUNIT_TEST(testSetUri16);
+  CPPUNIT_TEST(testSetUri18);
+  CPPUNIT_TEST(testSetUri19);
+  CPPUNIT_TEST(testSetUri20);
+  CPPUNIT_TEST(testSetUri_username);
+  CPPUNIT_TEST(testSetUri_usernamePassword);
+  CPPUNIT_TEST(testSetUri_zeroUsername);
+  CPPUNIT_TEST(testSetUri_ipv6);
+  CPPUNIT_TEST(testInnerLink);
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  void testSetUri1();
+  void testSetUri2();
+  void testSetUri3();
+  void testSetUri4();
+  void testSetUri5();
+  void testSetUri6();
+  void testSetUri7();
+  void testSetUri8();
+  void testSetUri9();
+  void testSetUri10();
+  void testSetUri11();
+  void testSetUri12();
+  void testSetUri13();
+  void testSetUri14();
+  void testSetUri15();
+  void testSetUri16();
+  void testSetUri18();
+  void testSetUri19();
+  void testSetUri20();
+  void testSetUri_username();
+  void testSetUri_usernamePassword();
+  void testSetUri_zeroUsername();
+  void testSetUri_ipv6();
+  void testInnerLink();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( UriTest );
+
+void UriTest::testSetUri1()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)80, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.password);
+  CPPUNIT_ASSERT(!us.ipv6LiteralAddress);
+}
+
+void UriTest::testSetUri2()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com:8080/index.html");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)8080, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri3()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/aria2/index.html");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)80, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/aria2"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri4()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/aria2/aria3/index.html");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)80, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/aria2/aria3"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri5()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/aria2/aria3/");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)80, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/aria2/aria3"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri6()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/aria2/aria3");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)80, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria.rednoah.com"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/aria2"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria3"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri7()
+{
+  UriStruct us;
+  bool v = parse(us, "http://");
+
+  CPPUNIT_ASSERT(!v);
+}
+
+void UriTest::testSetUri8()
+{
+  UriStruct us;
+  bool v = parse(us, "http:/aria.rednoah.com");
+
+  CPPUNIT_ASSERT(!v);
+}
+
+void UriTest::testSetUri9()
+{
+  UriStruct us;
+  bool v = parse(us, "h");
+
+  CPPUNIT_ASSERT(!v);
+}
+
+void UriTest::testSetUri10()
+{
+  UriStruct us;
+  bool v = parse(us, "");
+
+  CPPUNIT_ASSERT(!v);
+}
+
+void UriTest::testSetUri11()
+{
+  UriStruct us;
+  bool v = parse(us, "http://host?query/");
+
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("?query/"), us.query);
+}
+
+void UriTest::testSetUri12()
+{
+  UriStruct us;
+  bool v = parse(us, "http://host?query");
+  
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("?query"), us.query);
+}
+
+void UriTest::testSetUri13()
+{
+  UriStruct us;
+  bool v = parse(us, "http://host/?query");
+  
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("?query"), us.query);
+}
+
+void UriTest::testSetUri14()
+{
+  UriStruct us;
+  bool v = parse(us, "http://host:8080/abc?query");
+  
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)8080, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("abc"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("?query"), us.query);
+}
+
+void UriTest::testSetUri15()
+{
+  UriStruct us;
+  // 2 slashes after host name and dir
+  bool v = parse(us, "http://host//dir1/dir2//file");
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/dir1/dir2"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("file"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri16()
+{
+  UriStruct us;
+  // 2 slashes before file
+  bool v = parse(us, "http://host//file");
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("http"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL(std::string("host"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("file"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+void UriTest::testSetUri18()
+{
+  UriStruct us;
+  bool v = parse(us, "http://1/");
+
+  CPPUNIT_ASSERT(v);
+}
+
+void UriTest::testSetUri19()
+{
+  UriStruct us;
+  // No host
+  bool v = parse(us, "http://user@");
+
+  CPPUNIT_ASSERT(!v);
+}
+
+void UriTest::testSetUri20()
+{
+  UriStruct us;
+  bool v;
+  // Invalid port
+  v = parse(us, "http://localhost:65536");
+  CPPUNIT_ASSERT(!v);
+  v = parse(us, "http://localhost:65535");
+  CPPUNIT_ASSERT(v);
+  v = parse(us, "http://localhost:-80");
+  CPPUNIT_ASSERT(!v);
+}
+  
+void UriTest::testSetUri_zeroUsername()
+{
+  UriStruct us;
+  CPPUNIT_ASSERT(parse(us, "ftp://@localhost/download/aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)21, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/download"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.password);
+
+  CPPUNIT_ASSERT(parse(us, "ftp://:@localhost/download/aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)21, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/download"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.password);
+
+  CPPUNIT_ASSERT(parse(us,
+                       "ftp://:pass@localhost/download/aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)21, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/download"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string("pass"), us.password);
+
+}
+
+void UriTest::testSetUri_username()
+{
+  UriStruct us;
+  CPPUNIT_ASSERT
+    (parse(us, "ftp://aria2@user@localhost/download/aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)21, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/download"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2@user"), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.password);
+}
+
+void UriTest::testSetUri_usernamePassword()
+{
+  UriStruct us;
+  CPPUNIT_ASSERT(parse(us,
+                       "ftp://aria2@user%40:aria2@pass%40@localhost/download/"
+                       "aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ftp"), us.protocol);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)21, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("localhost"), us.host);
+  CPPUNIT_ASSERT_EQUAL(std::string("/download"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2@user@"), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2@pass@"), us.password);
+
+  // make sure that after new uri is set, username and password are updated.
+  CPPUNIT_ASSERT(parse(us, "ftp://localhost/download/aria2-1.0.0.tar.bz2"));
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.username);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.password);
+}
+
+void UriTest::testSetUri_ipv6()
+{
+  UriStruct us;
+  CPPUNIT_ASSERT(!parse(us, "http://[::1"));
+  CPPUNIT_ASSERT(parse(us, "http://[::1]"));
+  CPPUNIT_ASSERT_EQUAL(std::string("::1"), us.host);
+
+  CPPUNIT_ASSERT(parse(us, "http://[::1]:8000/dir/file"));
+  CPPUNIT_ASSERT_EQUAL(std::string("::1"), us.host);
+  CPPUNIT_ASSERT_EQUAL((uint16_t)8000, us.port);
+  CPPUNIT_ASSERT_EQUAL(std::string("/dir"), us.dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("file"), us.file);
+  CPPUNIT_ASSERT(us.ipv6LiteralAddress);
+}
+
+void UriTest::testInnerLink()
+{
+  UriStruct us;
+  bool v = parse(us, "http://aria.rednoah.com/index.html#download");
+  CPPUNIT_ASSERT(v);
+  CPPUNIT_ASSERT_EQUAL(std::string("index.html"), us.file);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), us.query);
+}
+
+} // namespace uri
+
+} // namespace aria2