Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Revert "URI parsing in folly""
Summary: Now that the third_party link was updated in https://phabricator.fb.com/D778617, we're good. Test Plan: fbconfig -r thrift && fbmake runtests_opt Reviewed By: chip@fb.com FB internal diff: D778707
- Loading branch information
Showing
8 changed files
with
742 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright 2013 Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef FOLLY_URI_H_ | ||
#error This file may only be included from folly/Uri.h | ||
#endif | ||
|
||
#include "folly/Conv.h" | ||
|
||
namespace folly { | ||
|
||
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); | ||
} | ||
toAppend(path_, &str); | ||
if (!query_.empty()) { | ||
toAppend("?", query_, &str); | ||
} | ||
if (!fragment_.empty()) { | ||
toAppend("#", fragment_, &str); | ||
} | ||
return str; | ||
} | ||
|
||
} // namespace folly | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Copyright 2013 Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "folly/Uri.h" | ||
|
||
#include <ctype.h> | ||
#include <boost/regex.hpp> | ||
|
||
namespace folly { | ||
|
||
namespace { | ||
|
||
fbstring submatch(const boost::cmatch& m, size_t idx) { | ||
auto& sub = m[idx]; | ||
return fbstring(sub.first, sub.second); | ||
} | ||
|
||
template <class String> | ||
void toLower(String& s) { | ||
for (auto& c : s) { | ||
c = tolower(c); | ||
} | ||
} | ||
|
||
} // namespace | ||
|
||
Uri::Uri(StringPiece str) : port_(0) { | ||
static const boost::regex uriRegex( | ||
"([a-zA-Z][a-zA-Z0-9+.-]*):" // scheme: | ||
"([^?#]*)" // authority and path | ||
"(?:\\?([^#]*))?" // ?query | ||
"(?:#(.*))?"); // #fragment | ||
static const boost::regex authorityAndPathRegex("//([^/]*)(/.*)?"); | ||
|
||
boost::cmatch match; | ||
if (UNLIKELY(!boost::regex_match(str.begin(), str.end(), match, uriRegex))) { | ||
throw std::invalid_argument("invalid URI"); | ||
} | ||
|
||
scheme_ = submatch(match, 1); | ||
toLower(scheme_); | ||
|
||
StringPiece authorityAndPath(match[2].first, match[2].second); | ||
boost::cmatch authorityAndPathMatch; | ||
if (!boost::regex_match(authorityAndPath.begin(), | ||
authorityAndPath.end(), | ||
authorityAndPathMatch, | ||
authorityAndPathRegex)) { | ||
// Does not start with //, doesn't have authority | ||
path_ = authorityAndPath.fbstr(); | ||
} else { | ||
static const boost::regex authorityRegex( | ||
"(?:([^@:]*)(?::([^@]*))?@)?" // username, password | ||
"(\\[[^\\]]*\\]|[^\\[:]*)" // host (IP-literal, dotted-IPv4, or | ||
// named host) | ||
"(?::(\\d*))?"); // port | ||
|
||
auto authority = authorityAndPathMatch[1]; | ||
boost::cmatch authorityMatch; | ||
if (!boost::regex_match(authority.first, | ||
authority.second, | ||
authorityMatch, | ||
authorityRegex)) { | ||
throw std::invalid_argument("invalid URI authority"); | ||
} | ||
|
||
StringPiece port(authorityMatch[4].first, authorityMatch[4].second); | ||
if (!port.empty()) { | ||
port_ = to<uint32_t>(port); | ||
} | ||
|
||
username_ = submatch(authorityMatch, 1); | ||
password_ = submatch(authorityMatch, 2); | ||
host_ = submatch(authorityMatch, 3); | ||
path_ = submatch(authorityAndPathMatch, 2); | ||
} | ||
|
||
query_ = submatch(match, 3); | ||
fragment_ = submatch(match, 4); | ||
} | ||
|
||
} // namespace folly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2013 Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef FOLLY_URI_H_ | ||
#define FOLLY_URI_H_ | ||
|
||
#include "folly/String.h" | ||
|
||
namespace folly { | ||
|
||
/** | ||
* Class representing a URI. | ||
* | ||
* Consider http://www.facebook.com/foo/bar?key=foo#anchor | ||
* | ||
* The URI is broken down into its parts: scheme ("http"), authority | ||
* (ie. host and port, in most cases: "www.facebook.com"), path | ||
* ("/foo/bar"), query ("key=foo") and fragment ("anchor"). The scheme is | ||
* lower-cased. | ||
* | ||
* If this Uri represents a URL, note that, to prevent ambiguity, the component | ||
* parts are NOT percent-decoded; you should do this yourself with | ||
* uriUnescape() (for the authority and path) and uriUnescape(..., | ||
* UriEscapeMode::QUERY) (for the query, but probably only after splitting at | ||
* '&' to identify the individual parameters). | ||
*/ | ||
class Uri { | ||
public: | ||
/** | ||
* Parse a Uri from a string. Throws std::invalid_argument on parse error. | ||
*/ | ||
explicit Uri(StringPiece str); | ||
|
||
const fbstring& scheme() const { return scheme_; } | ||
const fbstring& username() const { return username_; } | ||
const fbstring& password() const { return password_; } | ||
const fbstring& host() const { return host_; } | ||
uint32_t port() const { return port_; } | ||
const fbstring& path() const { return path_; } | ||
const fbstring& query() const { return query_; } | ||
const fbstring& fragment() const { return fragment_; } | ||
|
||
template <class String> | ||
String toString() const; | ||
|
||
std::string str() const { return toString<std::string>(); } | ||
fbstring fbstr() const { return toString<fbstring>(); } | ||
|
||
private: | ||
fbstring scheme_; | ||
fbstring username_; | ||
fbstring password_; | ||
fbstring host_; | ||
uint32_t port_; | ||
fbstring path_; | ||
fbstring query_; | ||
fbstring fragment_; | ||
}; | ||
|
||
} // namespace folly | ||
|
||
#include "folly/Uri-inl.h" | ||
|
||
#endif /* FOLLY_URI_H_ */ |
Oops, something went wrong.