aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-09 23:36:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-09 23:36:58 +0200
commit45a4174d5269661cfbd46e56acbbdc6551c6fbe2 (patch)
tree9146ca1bcb20797c80cb291722ba819fff4ce632
parent9239c606dfadf96a5a69e2581ddb54064afcdfa7 (diff)
Support https protocol for repository_location
-rw-r--r--bpkg/manifest10
-rw-r--r--bpkg/manifest.cxx24
-rw-r--r--tests/repository-location/driver.cxx49
3 files changed, 75 insertions, 8 deletions
diff --git a/bpkg/manifest b/bpkg/manifest
index d4c34d6..d443c49 100644
--- a/bpkg/manifest
+++ b/bpkg/manifest
@@ -458,6 +458,15 @@ namespace bpkg
return port_;
}
+ bool
+ secure () const
+ {
+ if (local ())
+ throw std::logic_error ("local location");
+
+ return secure_;
+ }
+
// Note that this is not necessarily syntactically the same string
// as what was used to initialize this location. But it should be
// semantically equivalent. String representation of an empty
@@ -471,6 +480,7 @@ namespace bpkg
std::string host_;
std::uint16_t port_;
butl::dir_path path_;
+ bool secure_;
};
inline std::ostream&
diff --git a/bpkg/manifest.cxx b/bpkg/manifest.cxx
index 48e7a99..ac746e6 100644
--- a/bpkg/manifest.cxx
+++ b/bpkg/manifest.cxx
@@ -1221,12 +1221,16 @@ namespace bpkg
if (!b.empty () && b.relative ())
throw invalid_argument ("base relative filesystem path");
- if (::strncasecmp (l.c_str (), "http://", 7) == 0)
+ secure_ = false;
+
+ if (::strncasecmp (l.c_str (), "http://", 7) == 0 ||
+ (secure_ = ::strncasecmp (l.c_str (), "https://", 8) == 0))
{
// Split location into host, port and path components. Calculate
// canonical name <host> part removing www. and pkg. prefixes.
//
- auto p (l.find ('/', 7));
+ size_t host_offset (secure_ ? 8 : 7);
+ auto p (l.find ('/', host_offset));
// The remote repository location with no path specified is not a valid
// one. Keep the path_ member empty so the later check for emptiness
@@ -1241,7 +1245,7 @@ namespace bpkg
// Put the lower-cased version of the host part into host_.
// Chances are good it will stay unmodified.
//
- transform (l.cbegin () + 7,
+ transform (l.cbegin () + host_offset,
p == string::npos ? l.cend () : l.cbegin () + p,
back_inserter (host_),
lowercase);
@@ -1332,16 +1336,19 @@ namespace bpkg
// speaking we can end up with comething bogus like "com"
// if the host is "pkg.com".
//
+ bool bpkg (false);
if (host_.compare (0, 4, "www.") == 0 ||
- host_.compare (0, 4, "pkg.") == 0)
- canonical_name_.assign (host_, 4, string::npos);
+ host_.compare (0, 4, "pkg.") == 0 ||
+ (bpkg = host_.compare (0, 5, "bpkg.") == 0))
+ canonical_name_.assign (host_, bpkg ? 5 : 4, string::npos);
else
canonical_name_ = host_;
// For canonical name and for the HTTP protocol, treat a.com
- // and a.com:80 as the same name.
+ // and a.com:80 as the same name. The same rule apply the HTTPS protocol
+ // and the port 443.
//
- if (port_ != 0 && port_ != 80)
+ if (port_ != 0 && port_ != (secure_ ? 443 : 80))
canonical_name_ += ':' + to_string (port_);
}
else
@@ -1357,6 +1364,7 @@ namespace bpkg
host_ = b.host_;
port_ = b.port_;
path_ = b.path_ / path_;
+ secure_ = b.secure_;
// Set canonical name to the base location canonical name host
// part. The path part of the canonical name is calculated below.
@@ -1450,7 +1458,7 @@ namespace bpkg
if (local ())
return path_.string ();
- string p ("http://" + host_);
+ string p ((secure_ ? "https://" : "http://") + host_);
if (port_ != 0)
p += ":" + to_string (port_);
diff --git a/tests/repository-location/driver.cxx b/tests/repository-location/driver.cxx
index cbd76f9..5d88b0d 100644
--- a/tests/repository-location/driver.cxx
+++ b/tests/repository-location/driver.cxx
@@ -99,6 +99,7 @@ main (int argc, char* argv[])
assert (bad_location ("aaa/bbb"));
assert (bad_location ("/aaa/bbb"));
assert (bad_location ("http://aa"));
+ assert (bad_location ("https://aa"));
assert (bad_location ("http://aa/"));
assert (bad_location ("http://aa/b/.."));
assert (bad_location ("http://aa/."));
@@ -153,11 +154,25 @@ main (int argc, char* argv[])
repository_location l ("http://www.a.com:80/1/aa/bb");
assert (l.string () == "http://www.a.com:80/1/aa/bb");
assert (l.canonical_name () == "a.com/aa/bb");
+ assert (!l.secure ());
+ }
+ {
+ repository_location l ("https://www.a.com:443/1/aa/bb");
+ assert (l.string () == "https://www.a.com:443/1/aa/bb");
+ assert (l.canonical_name () == "a.com/aa/bb");
+ assert (l.secure ());
}
{
repository_location l ("http://www.a.com:8080/dd/1/aa/bb");
assert (l.string () == "http://www.a.com:8080/dd/1/aa/bb");
assert (l.canonical_name () == "a.com:8080/aa/bb");
+ assert (!l.secure ());
+ }
+ {
+ repository_location l ("https://www.a.com:444/dd/1/aa/bb");
+ assert (l.string () == "https://www.a.com:444/dd/1/aa/bb");
+ assert (l.canonical_name () == "a.com:444/aa/bb");
+ assert (l.secure ());
}
{
repository_location l ("http://a.com/a/b/../c/1/aa/../bb");
@@ -165,11 +180,26 @@ main (int argc, char* argv[])
assert (l.canonical_name () == "a.com/bb");
}
{
+ repository_location l ("https://a.com/a/b/../c/1/aa/../bb");
+ assert (l.string () == "https://a.com/a/c/1/bb");
+ assert (l.canonical_name () == "a.com/bb");
+ }
+ {
repository_location l ("http://www.CPPget.org/qw/1/a/b/");
assert (l.string () == "http://www.cppget.org/qw/1/a/b");
assert (l.canonical_name () == "cppget.org/a/b");
}
{
+ repository_location l ("http://pkg.CPPget.org/qw/1/a/b/");
+ assert (l.string () == "http://pkg.cppget.org/qw/1/a/b");
+ assert (l.canonical_name () == "cppget.org/a/b");
+ }
+ {
+ repository_location l ("http://bpkg.CPPget.org/qw/1/a/b/");
+ assert (l.string () == "http://bpkg.cppget.org/qw/1/a/b");
+ assert (l.canonical_name () == "cppget.org/a/b");
+ }
+ {
repository_location l ("http://abc.cppget.org/qw/1/a/b/");
assert (l.string () == "http://abc.cppget.org/qw/1/a/b");
assert (l.canonical_name () == "abc.cppget.org/a/b");
@@ -180,6 +210,11 @@ main (int argc, char* argv[])
assert (l.canonical_name () == "www.cppget.org/a/b");
}
{
+ repository_location l ("http://bpkg.www.cppget.org/qw/1/a/b/");
+ assert (l.string () == "http://bpkg.www.cppget.org/qw/1/a/b");
+ assert (l.canonical_name () == "www.cppget.org/a/b");
+ }
+ {
repository_location l ("http://cppget.org/qw//1/a//b/");
assert (l.string () == "http://cppget.org/qw/1/a/b");
assert (l.canonical_name () == "cppget.org/a/b");
@@ -195,6 +230,12 @@ main (int argc, char* argv[])
assert (l2.canonical_name () == "stable.cppget.org/math");
}
{
+ repository_location l1 ("https://stable.cppget.org/1/misc");
+ repository_location l2 ("../../1/math", l1);
+ assert (l2.string () == "https://stable.cppget.org/1/math");
+ assert (l2.canonical_name () == "stable.cppget.org/math");
+ }
+ {
repository_location l1 ("http://stable.cppget.org/1/misc");
repository_location l2 ("../math", l1);
assert (l2.string () == "http://stable.cppget.org/1/math");
@@ -205,6 +246,14 @@ main (int argc, char* argv[])
repository_location l2 ("../1/math", l1);
assert (l2.string () == "http://www.stable.cppget.org:8080/1/math");
assert (l2.canonical_name () == "stable.cppget.org:8080/math");
+ assert (!l2.secure ());
+ }
+ {
+ repository_location l1 ("https://www.stable.cppget.org:444/1");
+ repository_location l2 ("../1/math", l1);
+ assert (l2.string () == "https://www.stable.cppget.org:444/1/math");
+ assert (l2.canonical_name () == "stable.cppget.org:444/math");
+ assert (l2.secure ());
}
{
repository_location l1 ("/var/r1/1/misc");