Просмотр исходного кода

show URI.Path in all acquire item descriptions

It is a rather strange sight that index items use SiteOnly which strips
the Path, while e.g. deb files are downloaded with NoUserPassword which
does not. Important to note here is that for the file transport Path is
pretty important as there is no Host which would be displayed by Site,
which always resulted in "interesting" unspecific errors for "file:".

Adding a 'middle' ground between the two which does show the Path but
potentially modifies it (it strips a pending / at the end if existing)
solves this "file:" issue, syncs the output and in the end helps to
identify which file is meant exactly in progress output and co as a
single site can have multiple repositories in different paths.
David Kalnischkies лет назад: 11
Родитель
Сommit
1da3b7b8e1

+ 11 - 4
apt-pkg/contrib/strutl.cc

@@ -1637,8 +1637,6 @@ URI::operator string()
 }
 									/*}}}*/
 // URI::SiteOnly - Return the schema and site for the URI		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 string URI::SiteOnly(const string &URI)
 {
    ::URI U(URI);
@@ -1648,9 +1646,18 @@ string URI::SiteOnly(const string &URI)
    return U;
 }
 									/*}}}*/
+// URI::ArchiveOnly - Return the schema, site and cleaned path for the URI /*{{{*/
+string URI::ArchiveOnly(const string &URI)
+{
+   ::URI U(URI);
+   U.User.clear();
+   U.Password.clear();
+   if (U.Path.empty() == false && U.Path[U.Path.length() - 1] == '/')
+      U.Path.erase(U.Path.length() - 1);
+   return U;
+}
+									/*}}}*/
 // URI::NoUserPassword - Return the schema, site and path for the URI	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 string URI::NoUserPassword(const string &URI)
 {
    ::URI U(URI);

+ 1 - 0
apt-pkg/contrib/strutl.h

@@ -167,6 +167,7 @@ class URI
    inline void operator =(const std::string &From) {CopyFrom(From);}
    inline bool empty() {return Access.empty();};
    static std::string SiteOnly(const std::string &URI);
+   static std::string ArchiveOnly(const std::string &URI);
    static std::string NoUserPassword(const std::string &URI);
    
    URI(std::string Path) {CopyFrom(Path);}

+ 5 - 5
apt-pkg/deb/debindexfile.cc

@@ -57,7 +57,7 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
 				   pkgSrcRecords::File const &File) const
 {
    string Res;
-   Res = ::URI::NoUserPassword(URI) + ' ';
+   Res = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")
@@ -116,7 +116,7 @@ string debSourcesIndex::Describe(bool Short) const
 /* */
 string debSourcesIndex::Info(const char *Type) const
 {
-   string Info = ::URI::NoUserPassword(URI) + ' ';
+   string Info = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")
@@ -210,7 +210,7 @@ debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string
 /* This is a shorter version that is designed to be < 60 chars or so */
 string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
 {
-   string Res = ::URI::NoUserPassword(URI) + ' ';
+   string Res = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")
@@ -248,7 +248,7 @@ string debPackagesIndex::Describe(bool Short) const
 /* */
 string debPackagesIndex::Info(const char *Type) const 
 {
-   string Info = ::URI::NoUserPassword(URI) + ' ';
+   string Info = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")
@@ -473,7 +473,7 @@ string debTranslationsIndex::Describe(bool Short) const
 /* */
 string debTranslationsIndex::Info(const char *Type) const 
 {
-   string Info = ::URI::NoUserPassword(URI) + ' ';
+   string Info = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")

+ 2 - 2
apt-pkg/deb/debmetaindex.cc

@@ -25,7 +25,7 @@ using namespace std;
 
 string debReleaseIndex::MetaIndexInfo(const char *Type) const
 {
-   string Info = ::URI::SiteOnly(URI) + ' ';
+   string Info = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    {
       if (Dist != "/")
@@ -105,7 +105,7 @@ void foreachTarget(std::string const URI, std::string const Dist,
    else
       baseURI += "dists/" + Dist + "/";
    std::string const Release = (Dist == "/") ? "" : Dist;
-   std::string const Site = ::URI::SiteOnly(URI);
+   std::string const Site = ::URI::ArchiveOnly(URI);
    std::vector<std::string> lang = APT::Configuration::getLanguages(true);
    if (lang.empty())
       lang.push_back("none");

+ 1 - 1
test/integration/test-apt-cache

@@ -50,7 +50,7 @@ testsuccessequal 'bar' aptcache pkgnames bar
 testsuccessequal 'fancy
 foo' aptcache pkgnames f
 
-testsuccessequal "       foo |          1 | file:$(readlink -f .)/aptarchive/ unstable/main amd64 Packages" aptcache madison foo
+testsuccessequal "       foo |          1 | file:$(readlink -f .)/aptarchive unstable/main amd64 Packages" aptcache madison foo
 
 ### depends
 

+ 1 - 1
test/integration/test-apt-cli-show

@@ -32,7 +32,7 @@ Maintainer: Joe Sixpack <joe@example.org>
 Installed-Size: 43.0 kB
 Download-Size: unknown
 APT-Manual-Installed: yes
-APT-Sources: file:$APTARCHIVE/ unstable/main i386 Packages
+APT-Sources: file:$APTARCHIVE unstable/main i386 Packages
 Description: Some description 
  That has multiple lines
 " apt show foo

+ 6 - 6
test/integration/test-apt-get-update-unauth-warning

@@ -19,11 +19,11 @@ APTARCHIVE=$(readlink -f ./aptarchive)
 rm -f $APTARCHIVE/dists/unstable/*Release*
 
 # update without authenticated files leads to warning
-testfailureequal "Ign file: unstable InRelease
+testfailureequal "Ign file:$APTARCHIVE unstable InRelease
   File not found
-Err file: unstable Release
+Err file:$APTARCHIVE unstable Release
   File not found
-W: The repository 'file: unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository.
+W: The repository 'file:$APTARCHIVE unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository.
 E: Use --allow-insecure-repositories to force the update" aptget update --no-allow-insecure-repositories
 
 # no package foo
@@ -32,12 +32,12 @@ testequal 'lock
 partial' ls rootdir/var/lib/apt/lists
 
 # allow override
-testwarningequal "Ign file: unstable InRelease
+testwarningequal "Ign file:$APTARCHIVE unstable InRelease
   File not found
-Ign file: unstable Release
+Ign file:$APTARCHIVE unstable Release
   File not found
 Reading package lists...
-W: The repository 'file: unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository." aptget update --allow-insecure-repositories
+W: The repository 'file:$APTARCHIVE unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository." aptget update --allow-insecure-repositories
 # ensure we can not install the package
 testfailureequal "WARNING: The following packages cannot be authenticated!
   foo

+ 1 - 1
test/integration/test-apt-translation-has-no-packages

@@ -38,4 +38,4 @@ testsuccessequal "foo:
   Candidate: 1.0
   Version table:
      1.0 0
-        500 file:$APTARCHIVE/ unstable/main amd64 Packages" aptcache policy foo
+        500 file:$APTARCHIVE unstable/main amd64 Packages" aptcache policy foo

+ 3 - 3
test/integration/test-apt-update-nofallback

@@ -33,7 +33,7 @@ EOF
 
 assert_update_is_refused_and_last_good_state_used()
 {
-    testfailuremsg "E: The repository 'file: unstable Release' is no longer signed." aptget update
+    testfailuremsg "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update
 
     assert_repo_is_intact
 }
@@ -171,7 +171,7 @@ test_inrelease_to_invalid_inrelease()
     sed -i 's/^Codename:.*/Codename: evil!/' $APTARCHIVE/dists/unstable/InRelease
     inject_evil_package
 
-    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
+    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file:${APTARCHIVE} unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
 
 W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease  The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
 
@@ -195,7 +195,7 @@ test_release_gpg_to_invalid_release_release_gpg()
     echo "Some evil data" >>  $APTARCHIVE/dists/unstable/Release
     inject_evil_package
 
-    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
+    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file:${APTARCHIVE} unstable Release: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
 
 W: Failed to fetch file:${APTARCHIVE}/dists/unstable/Release.gpg  The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
 

+ 3 - 3
test/integration/test-apt-update-rollback

@@ -78,7 +78,7 @@ test_inrelease_to_valid_release() {
     rm $APTARCHIVE/dists/unstable/Release.gpg
 
     # update fails
-    testfailureequal "E: The repository 'file: unstable Release' is no longer signed." aptget update -qq
+    testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq
 
     # test that security downgrade was not successful
     testfileequal lists.before "$(listcurrentlistsdirectory)"
@@ -101,7 +101,7 @@ test_inrelease_to_release_reverts_all() {
     break_repository_sources_index '+1hour'
 
     # ensure error
-    testfailureequal "E: The repository 'file: unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1
+    testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1
 
     # ensure that the Packages file is also rolled back
     testfileequal lists.before "$(listcurrentlistsdirectory)"
@@ -144,7 +144,7 @@ test_inrelease_to_unauth_inrelease() {
 
     signreleasefiles 'Marvin Paranoid'
 
-    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
+    testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file:${APTARCHIVE} unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
 
 W: Failed to fetch file:$APTARCHIVE/dists/unstable/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
 

+ 1 - 1
test/integration/test-bug-543966-downgrade-below-1000-pin

@@ -13,7 +13,7 @@ insertinstalledpackage 'base-files' 'all' '5.0.0-1'
 setupaptarchive
 
 STATUS=$(readlink -f rootdir/var/lib/dpkg/status)
-APTARCHIVE="$(readlink -f aptarchive)/"
+APTARCHIVE="$(readlink -f aptarchive)"
 
 testsuccessequal "base-files:
   Installed: 5.0.0-1

+ 3 - 2
test/integration/test-bug-595691-empty-and-broken-archive-files

@@ -49,6 +49,7 @@ createemptyfile() {
 }
 
 testoverfile() {
+	local APTARCHIVE="$(readlink -f ./aptarchive)"
 	forcecompressor "$1"
 
 	createemptyfile 'en'
@@ -63,9 +64,9 @@ testoverfile() {
 	testaptgetupdate 'Reading package lists...' "empty archive Packages.$COMPRESS over file"
 
 	createemptyfile 'Packages'
-	testaptgetupdate "Err file:  Packages
+	testaptgetupdate "Err file:$APTARCHIVE  Packages
   Empty files can't be valid archives
-W: Failed to fetch ${COMPRESSOR}:$(readlink -f aptarchive/Packages.$COMPRESS)  Empty files can't be valid archives
+W: Failed to fetch ${COMPRESSOR}:${APTARCHIVE}/Packages.$COMPRESS  Empty files can't be valid archives
 
 E: Some index files failed to download. They have been ignored, or old ones used instead." "empty file Packages.$COMPRESS over file"
 }

+ 1 - 1
test/integration/test-cve-2013-1051-InRelease-parsing

@@ -12,7 +12,7 @@ insertpackage 'stable' 'good-pkg' 'all' '1.0'
 setupaptarchive
 
 changetowebserver
-ARCHIVE='http://localhost:8080/'
+ARCHIVE='http://localhost:8080'
 msgtest 'Initial apt-get update should work with' 'InRelease'
 testsuccess --nomsg aptget update
 

+ 4 - 4
test/integration/test-policy-pinning

@@ -20,7 +20,7 @@ testequalpolicy() {
 	testsuccessequal "Package files:
  $(echo "$SP" | awk '{ printf("%3s\n",$0) }') ${STATUS}
      release a=now
- $(echo "$AP" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}/  Packages
+ $(echo "$AP" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}  Packages
      release c=
 Pinned packages:" aptcache policy $*
 }
@@ -105,11 +105,11 @@ testequalpolicycoolstuff() {
 	local BPO1ARCHIVE=""
 	local BPO2ARCHIVE=""
 	if [ ! "$7" = "2.0~bpo2" ]; then
-		BPO1ARCHIVE="        $(echo "$AB" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}/ backports/main i386 Packages"
+		BPO1ARCHIVE="        $(echo "$AB" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE} backports/main i386 Packages"
 	else
 		BPO2ARCHIVE="
      2.0~bpo2 $PB
-        $(echo "$AB" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}/ backports/main i386 Packages"
+        $(echo "$AB" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE} backports/main i386 Packages"
 		SB="$(echo "$SB" | tail -n 1)"
 		shift
 	fi
@@ -121,7 +121,7 @@ testequalpolicycoolstuff() {
  $IB 2.0~bpo1 $PB
 ${BPO1ARCHIVE}$SB
  $IS 1.0 $PB
-        $(echo "$AS" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}/ stable/main i386 Packages$SS" \
+        $(echo "$AS" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE} stable/main i386 Packages$SS" \
 		aptcache policy coolstuff -o Policy=${INSTALLED}-${CANDIDATE}-${AB}-${AS}-${PB} $*
 }
 

+ 2 - 2
test/integration/test-releasefile-verification

@@ -41,7 +41,7 @@ The following NEW packages will be installed:
   apt
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 After this operation, 5370 kB of additional disk space will be used.
-Get:1 http://localhost:8080/  apt 0.7.25.3
+Get:1 http://localhost:8080  apt 0.7.25.3
 Download complete and in download only mode' aptget install apt -dy
 }
 
@@ -54,7 +54,7 @@ The following NEW packages will be installed:
   apt
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 After this operation, 5808 kB of additional disk space will be used.
-Get:1 http://localhost:8080/  apt 0.8.0~pre1
+Get:1 http://localhost:8080  apt 0.8.0~pre1
 Download complete and in download only mode' aptget install apt -dy
 }
 

+ 14 - 14
test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum

@@ -148,8 +148,8 @@ testok() {
 	testsuccessequal "Reading package lists...
 Building dependency tree...
 Need to get 6 B of source archives.
-Get:1 http://localhost:8080/  $1 1.0 (dsc) [3 B]
-Get:2 http://localhost:8080/  $1 1.0 (tar) [3 B]
+Get:1 http://localhost:8080  $1 1.0 (dsc) [3 B]
+Get:2 http://localhost:8080  $1 1.0 (tar) [3 B]
 Download complete and in download only mode" aptget source -d "$@"
 	msgtest 'Files were successfully downloaded for' "$1"
 	testsuccess --nomsg test -e ${1}_1.0.dsc -a -e ${1}_1.0.tar.gz
@@ -175,11 +175,11 @@ testmismatch() {
 	testfailureequal "Reading package lists...
 Building dependency tree...
 Need to get 6 B of source archives.
-Get:1 http://localhost:8080/  $1 1.0 (dsc) [3 B]
-Err http://localhost:8080/  $1 1.0 (dsc)
+Get:1 http://localhost:8080  $1 1.0 (dsc) [3 B]
+Err http://localhost:8080  $1 1.0 (dsc)
   Hash Sum mismatch
-Get:2 http://localhost:8080/  $1 1.0 (tar) [3 B]
-Err http://localhost:8080/  $1 1.0 (tar)
+Get:2 http://localhost:8080  $1 1.0 (tar) [3 B]
+Err http://localhost:8080  $1 1.0 (tar)
   Hash Sum mismatch
 E: Failed to fetch http://localhost:8080/${1}_1.0.dsc  Hash Sum mismatch
 
@@ -203,8 +203,8 @@ Download complete and in download only mode" aptget source -d "$@" -o Acquire::F
 	testsuccessequal "Reading package lists...
 Building dependency tree...
 Need to get 6 B of source archives.
-Get:1 http://localhost:8080/  $1 1.0 (dsc) [3 B]
-Get:2 http://localhost:8080/  $1 1.0 (tar) [3 B]
+Get:1 http://localhost:8080  $1 1.0 (dsc) [3 B]
+Get:2 http://localhost:8080  $1 1.0 (tar) [3 B]
 Download complete and in download only mode" aptget source --allow-unauthenticated -d "$@" -o Acquire::ForceHash=ROT26
 	msgtest 'Files were downloaded unauthenticated as user allowed it' "$1"
 	testsuccess --nomsg test -e ${1}_1.0.dsc -a -e ${1}_1.0.tar.gz
@@ -240,9 +240,9 @@ testok pkg-mixed-ok
 testfailureequal 'Reading package lists...
 Building dependency tree...
 Need to get 6 B of source archives.
-Get:1 http://localhost:8080/  pkg-mixed-sha1-bad 1.0 (tar) [3 B]
-Get:2 http://localhost:8080/  pkg-mixed-sha1-bad 1.0 (dsc) [3 B]
-Err http://localhost:8080/  pkg-mixed-sha1-bad 1.0 (dsc)
+Get:1 http://localhost:8080  pkg-mixed-sha1-bad 1.0 (tar) [3 B]
+Get:2 http://localhost:8080  pkg-mixed-sha1-bad 1.0 (dsc) [3 B]
+Err http://localhost:8080  pkg-mixed-sha1-bad 1.0 (dsc)
   Hash Sum mismatch
 E: Failed to fetch http://localhost:8080/pkg-mixed-sha1-bad_1.0.dsc  Hash Sum mismatch
 
@@ -252,10 +252,10 @@ testsuccess --nomsg test ! -e pkg-mixed-sha1-bad_1.0.dsc -a -e pkg-mixed-sha1-ba
 testfailureequal 'Reading package lists...
 Building dependency tree...
 Need to get 6 B of source archives.
-Get:1 http://localhost:8080/  pkg-mixed-sha2-bad 1.0 (tar) [3 B]
-Err http://localhost:8080/  pkg-mixed-sha2-bad 1.0 (tar)
+Get:1 http://localhost:8080  pkg-mixed-sha2-bad 1.0 (tar) [3 B]
+Err http://localhost:8080  pkg-mixed-sha2-bad 1.0 (tar)
   Hash Sum mismatch
-Get:2 http://localhost:8080/  pkg-mixed-sha2-bad 1.0 (dsc) [3 B]
+Get:2 http://localhost:8080  pkg-mixed-sha2-bad 1.0 (dsc) [3 B]
 E: Failed to fetch http://localhost:8080/pkg-mixed-sha2-bad_1.0.tar.gz  Hash Sum mismatch
 
 E: Failed to fetch some archives.' aptget source -d pkg-mixed-sha2-bad

+ 39 - 0
test/libapt/uri_test.cc

@@ -13,6 +13,9 @@ TEST(URITest, BasicHTTP)
    EXPECT_EQ("www.debian.org", U.Host);
    EXPECT_EQ("/temp/test", U.Path);
    EXPECT_EQ("http://www.debian.org:90/temp/test", (std::string)U);
+   EXPECT_EQ("http://www.debian.org:90", URI::SiteOnly(U));
+   EXPECT_EQ("http://www.debian.org:90/temp/test", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://www.debian.org:90/temp/test", URI::NoUserPassword(U));
    // Login data
    U = URI("http://jgg:foo@ualberta.ca/blah");
    EXPECT_EQ("http", U.Access);
@@ -22,6 +25,9 @@ TEST(URITest, BasicHTTP)
    EXPECT_EQ("ualberta.ca", U.Host);
    EXPECT_EQ("/blah", U.Path);
    EXPECT_EQ("http://jgg:foo@ualberta.ca/blah", (std::string)U);
+   EXPECT_EQ("http://ualberta.ca", URI::SiteOnly(U));
+   EXPECT_EQ("http://ualberta.ca/blah", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://ualberta.ca/blah", URI::NoUserPassword(U));
 }
 TEST(URITest, SingeSlashFile)
 {
@@ -33,6 +39,9 @@ TEST(URITest, SingeSlashFile)
    EXPECT_EQ("", U.Host);
    EXPECT_EQ("/usr/bin/foo", U.Path);
    EXPECT_EQ("file:/usr/bin/foo", (std::string)U);
+   EXPECT_EQ("file:", URI::SiteOnly(U));
+   EXPECT_EQ("file:/usr/bin/foo", URI::ArchiveOnly(U));
+   EXPECT_EQ("file:/usr/bin/foo", URI::NoUserPassword(U));
 }
 TEST(URITest, BasicCDROM)
 {
@@ -44,6 +53,9 @@ TEST(URITest, BasicCDROM)
    EXPECT_EQ("Moo Cow Rom", U.Host);
    EXPECT_EQ("/debian", U.Path);
    EXPECT_EQ("cdrom://Moo Cow Rom/debian", (std::string)U);
+   EXPECT_EQ("cdrom://Moo Cow Rom", URI::SiteOnly(U));
+   EXPECT_EQ("cdrom://Moo Cow Rom/debian", URI::ArchiveOnly(U));
+   EXPECT_EQ("cdrom://Moo Cow Rom/debian", URI::NoUserPassword(U));
 }
 TEST(URITest, RelativeGzip)
 {
@@ -55,6 +67,9 @@ TEST(URITest, RelativeGzip)
    EXPECT_EQ(".", U.Host);
    EXPECT_EQ("/bar/cow", U.Path);
    EXPECT_EQ("gzip://./bar/cow", (std::string)U);
+   EXPECT_EQ("gzip://.", URI::SiteOnly(U));
+   EXPECT_EQ("gzip://./bar/cow", URI::ArchiveOnly(U));
+   EXPECT_EQ("gzip://./bar/cow", URI::NoUserPassword(U));
 }
 TEST(URITest, NoSlashFTP)
 {
@@ -66,6 +81,9 @@ TEST(URITest, NoSlashFTP)
    EXPECT_EQ("ftp.fr.debian.org", U.Host);
    EXPECT_EQ("/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", U.Path);
    EXPECT_EQ("ftp://ftp.fr.debian.org/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", (std::string)U);
+   EXPECT_EQ("ftp://ftp.fr.debian.org", URI::SiteOnly(U));
+   EXPECT_EQ("ftp://ftp.fr.debian.org/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", URI::ArchiveOnly(U));
+   EXPECT_EQ("ftp://ftp.fr.debian.org/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", URI::NoUserPassword(U));
 }
 TEST(URITest, RFC2732)
 {
@@ -77,6 +95,9 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("1080::8:800:200C:417A", U.Host);
    EXPECT_EQ("/foo", U.Path);
    EXPECT_EQ("http://[1080::8:800:200C:417A]/foo", (std::string)U);
+   EXPECT_EQ("http://[1080::8:800:200C:417A]", URI::SiteOnly(U));
+   EXPECT_EQ("http://[1080::8:800:200C:417A]/foo", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://[1080::8:800:200C:417A]/foo", URI::NoUserPassword(U));
    // with port
    U = URI("http://[::FFFF:129.144.52.38]:80/index.html");
    EXPECT_EQ("http", U.Access);
@@ -86,6 +107,9 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("::FFFF:129.144.52.38", U.Host);
    EXPECT_EQ("/index.html", U.Path);
    EXPECT_EQ("http://[::FFFF:129.144.52.38]:80/index.html", (std::string)U);
+   EXPECT_EQ("http://[::FFFF:129.144.52.38]:80", URI::SiteOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38]:80/index.html", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38]:80/index.html", URI::NoUserPassword(U));
    // extra colon
    U = URI("http://[::FFFF:129.144.52.38:]:80/index.html");
    EXPECT_EQ("http", U.Access);
@@ -95,6 +119,9 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("::FFFF:129.144.52.38:", U.Host);
    EXPECT_EQ("/index.html", U.Path);
    EXPECT_EQ("http://[::FFFF:129.144.52.38:]:80/index.html", (std::string)U);
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]:80", URI::SiteOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]:80/index.html", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]:80/index.html", URI::NoUserPassword(U));
    // extra colon port
    U = URI("http://[::FFFF:129.144.52.38:]/index.html");
    EXPECT_EQ("http", U.Access);
@@ -104,6 +131,9 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("::FFFF:129.144.52.38:", U.Host);
    EXPECT_EQ("/index.html", U.Path);
    EXPECT_EQ("http://[::FFFF:129.144.52.38:]/index.html", (std::string)U);
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]", URI::SiteOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]/index.html", URI::ArchiveOnly(U));
+   EXPECT_EQ("http://[::FFFF:129.144.52.38:]/index.html", URI::NoUserPassword(U));
    // My Evil Corruption of RFC 2732 to handle CDROM names!
    // Fun for the whole family! */
    U = URI("cdrom:[The Debian 1.2 disk, 1/2 R1:6]/debian/");
@@ -114,6 +144,9 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("The Debian 1.2 disk, 1/2 R1:6", U.Host);
    EXPECT_EQ("/debian/", U.Path);
    EXPECT_EQ("cdrom://[The Debian 1.2 disk, 1/2 R1:6]/debian/", (std::string)U);
+   EXPECT_EQ("cdrom://[The Debian 1.2 disk, 1/2 R1:6]", URI::SiteOnly(U));
+   EXPECT_EQ("cdrom://[The Debian 1.2 disk, 1/2 R1:6]/debian", URI::ArchiveOnly(U));
+   EXPECT_EQ("cdrom://[The Debian 1.2 disk, 1/2 R1:6]/debian/", URI::NoUserPassword(U));
    // no brackets
    U = URI("cdrom:Foo Bar Cow/debian/");
    EXPECT_EQ("cdrom", U.Access);
@@ -123,9 +156,15 @@ TEST(URITest, RFC2732)
    EXPECT_EQ("Foo Bar Cow", U.Host);
    EXPECT_EQ("/debian/", U.Path);
    EXPECT_EQ("cdrom://Foo Bar Cow/debian/", (std::string)U);
+   EXPECT_EQ("cdrom://Foo Bar Cow", URI::SiteOnly(U));
+   EXPECT_EQ("cdrom://Foo Bar Cow/debian", URI::ArchiveOnly(U));
+   EXPECT_EQ("cdrom://Foo Bar Cow/debian/", URI::NoUserPassword(U));
    // percent encoded
    U = URI("ftp://foo:b%40r@example.org");
    EXPECT_EQ("foo", U.User);
    EXPECT_EQ("b@r", U.Password);
    EXPECT_EQ("ftp://foo:b%40r@example.org/", (std::string) U);
+   EXPECT_EQ("ftp://example.org", URI::SiteOnly(U));
+   EXPECT_EQ("ftp://example.org", URI::ArchiveOnly(U));
+   EXPECT_EQ("ftp://example.org/", URI::NoUserPassword(U));
 }