template <class String>
String Uri::toString() const {
String str;
- toAppend(scheme_, "://", &str);
- if (!password_.empty()) {
- toAppend(username_, ":", password_, "@", &str);
- } else if (!username_.empty()) {
- toAppend(username_, "@", &str);
- }
- toAppend(host_, &str);
- if (port_ != 0) {
- toAppend(":", port_, &str);
+ if (hasAuthority_) {
+ toAppend(scheme_, "://", &str);
+ if (!password_.empty()) {
+ toAppend(username_, ":", password_, "@", &str);
+ } else if (!username_.empty()) {
+ toAppend(username_, "@", &str);
+ }
+ toAppend(host_, &str);
+ if (port_ != 0) {
+ toAppend(":", port_, &str);
+ }
+ } else {
+ toAppend(scheme_, ":", &str);
}
toAppend(path_, &str);
if (!query_.empty()) {
} // namespace
-Uri::Uri(StringPiece str) : port_(0) {
+Uri::Uri(StringPiece str) : hasAuthority_(false), port_(0) {
static const boost::regex uriRegex(
"([a-zA-Z][a-zA-Z0-9+.-]*):" // scheme:
"([^?#]*)" // authority and path
authorityAndPathMatch,
authorityAndPathRegex)) {
// Does not start with //, doesn't have authority
+ hasAuthority_ = false;
path_ = authorityAndPath.fbstr();
} else {
static const boost::regex authorityRegex(
port_ = to<uint16_t>(port);
}
+ hasAuthority_ = true;
username_ = submatch(authorityMatch, 1);
password_ = submatch(authorityMatch, 2);
host_ = submatch(authorityMatch, 3);
std::string str() const { return toString<std::string>(); }
fbstring fbstr() const { return toString<fbstring>(); }
- void setPort(uint16_t port) {port_ = port;}
+ void setPort(uint16_t port) {
+ hasAuthority_ = true;
+ port_ = port;
+ }
/**
* Get query parameters as key-value pairs.
fbstring username_;
fbstring password_;
fbstring host_;
+ bool hasAuthority_;
uint16_t port_;
fbstring path_;
fbstring query_;
EXPECT_EQ("/etc/motd", u.path());
EXPECT_EQ("", u.query());
EXPECT_EQ("", u.fragment());
- EXPECT_EQ("file:///etc/motd", u.fbstr());
+ EXPECT_EQ("file:/etc/motd", u.fbstr());
}
{
// success
}
}
+
+ // No authority (no "//") is valid
+ {
+ fbstring s("this:is/a/valid/uri");
+ Uri u(s);
+ EXPECT_EQ("this", u.scheme());
+ EXPECT_EQ("is/a/valid/uri", u.path());
+ EXPECT_EQ(s, u.fbstr());
+ }
+ {
+ fbstring s("this:is:another:valid:uri");
+ Uri u(s);
+ EXPECT_EQ("this", u.scheme());
+ EXPECT_EQ("is:another:valid:uri", u.path());
+ EXPECT_EQ(s, u.fbstr());
+ }
+ {
+ fbstring s("this:is@another:valid:uri");
+ Uri u(s);
+ EXPECT_EQ("this", u.scheme());
+ EXPECT_EQ("is@another:valid:uri", u.path());
+ EXPECT_EQ(s, u.fbstr());
+ }
}
/**