From: Tudor Bosman Date: Thu, 28 May 2015 20:59:56 +0000 (-0700) Subject: Fix toString() for authority-less URIs X-Git-Tag: v0.42.0~19 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5b39efc2656ebcd74b46775ad276c1ab06c3c54b;p=folly.git Fix toString() for authority-less URIs Summary: Uri("foo:bar").str() would incorrectly return "foo://bar" Test Plan: test added Reviewed By: savasp@fb.com, markisaa@fb.com Subscribers: folly-diffs@, yfeldblum, chalfant FB internal diff: D2107530 Tasks: 7248055 Signature: t1:2107530:1432837143:c100f148c07b5b141cc036b1b39e6c8317e9bbd6 --- diff --git a/folly/Uri-inl.h b/folly/Uri-inl.h index e9ec7321..812c400a 100644 --- a/folly/Uri-inl.h +++ b/folly/Uri-inl.h @@ -25,15 +25,19 @@ namespace folly { template 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()) { diff --git a/folly/Uri.cpp b/folly/Uri.cpp index 6d5befb9..9bff152b 100644 --- a/folly/Uri.cpp +++ b/folly/Uri.cpp @@ -37,7 +37,7 @@ void toLower(String& s) { } // 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 @@ -60,6 +60,7 @@ Uri::Uri(StringPiece str) : port_(0) { authorityAndPathMatch, authorityAndPathRegex)) { // Does not start with //, doesn't have authority + hasAuthority_ = false; path_ = authorityAndPath.fbstr(); } else { static const boost::regex authorityRegex( @@ -84,6 +85,7 @@ Uri::Uri(StringPiece str) : port_(0) { port_ = to(port); } + hasAuthority_ = true; username_ = submatch(authorityMatch, 1); password_ = submatch(authorityMatch, 2); host_ = submatch(authorityMatch, 3); diff --git a/folly/Uri.h b/folly/Uri.h index c8712160..739fc38f 100644 --- a/folly/Uri.h +++ b/folly/Uri.h @@ -76,7 +76,10 @@ class Uri { std::string str() const { return toString(); } fbstring fbstr() const { return toString(); } - void setPort(uint16_t port) {port_ = port;} + void setPort(uint16_t port) { + hasAuthority_ = true; + port_ = port; + } /** * Get query parameters as key-value pairs. @@ -105,6 +108,7 @@ class Uri { fbstring username_; fbstring password_; fbstring host_; + bool hasAuthority_; uint16_t port_; fbstring path_; fbstring query_; diff --git a/folly/test/UriTest.cpp b/folly/test/UriTest.cpp index 418bf259..12d8eafb 100644 --- a/folly/test/UriTest.cpp +++ b/folly/test/UriTest.cpp @@ -239,7 +239,7 @@ TEST(Uri, Simple) { 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()); } { @@ -389,6 +389,29 @@ TEST(Uri, Simple) { // 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()); + } } /**