Skip to content

Commit 3e3f7b0

Browse files
Will Wangfacebook-github-bot
Will Wang
authored andcommitted
Refactor getRedirectDestination With Static Public Helper
Summary: From message: getRedirectDestination is currently a private method inside `HTTPRedirectHandler`. Given a location header from a 3xx, it is able to output the url. This is a useful functionality. Refactor the private function `getRedirectDestination` to a public static function in `ParseURL`. Move the anon function `isSupportedScheme` to `ParseURL` instead. Reviewed By: hanidamlaj Differential Revision: D56788027 fbshipit-source-id: 36318459bcc28dd4a788d083d3746446a7bbc54f
1 parent eb35fdb commit 3e3f7b0

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

proxygen/lib/utils/ParseURL.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,53 @@ static bool validateScheme(folly::StringPiece url) {
5252
scheme.begin(), scheme.end(), [](auto _) { return std::isalpha(_); });
5353
}
5454

55+
bool ParseURL::isSupportedScheme(const std::string& location) {
56+
static const std::vector<std::string> supportedSchemes = {"http", "https"};
57+
std::size_t containsScheme = location.find("://");
58+
if (containsScheme == std::string::npos) {
59+
// Location doesn't contain a scheme, so use the one from the original URL
60+
return true;
61+
}
62+
63+
for (const std::string& scheme : supportedSchemes) {
64+
// Check to see whether or not it is a supported scheme
65+
if (location.compare(0, scheme.length(), scheme) == 0) {
66+
return true;
67+
}
68+
}
69+
return false;
70+
}
71+
72+
folly::Optional<std::string> ParseURL::getRedirectDestination(
73+
const std::string& url,
74+
const std::string& requestScheme,
75+
const std::string& location,
76+
const std::string& headerHost) noexcept {
77+
auto newUrl = ParseURL::parseURL(location);
78+
if (!newUrl) {
79+
DLOG(INFO) << "Unparsable location header=" << location;
80+
return folly::none;
81+
}
82+
if (!newUrl->hasHost()) {
83+
// New URL is relative
84+
folly::Expected<ParseURL, folly::Unit> oldURL = ParseURL::parseURL(url);
85+
if (!oldURL || !oldURL->hasHost()) {
86+
// Old URL was relative, try host header
87+
oldURL = ParseURL::parseURL(headerHost);
88+
if (!oldURL || !oldURL->hasHost()) {
89+
VLOG(2) << "Cannot determine destination for relative redirect "
90+
<< "location=" << location << " orig url=" << url
91+
<< " host=" << headerHost;
92+
return folly::none;
93+
}
94+
} // else oldURL was absolute and has a host
95+
return folly::to<std::string>(
96+
requestScheme, "://", oldURL->hostAndPort(), location);
97+
} else {
98+
return newUrl->url().str();
99+
}
100+
}
101+
55102
void ParseURL::parse(bool strict) noexcept {
56103
if (url_.size() == 1 && url_[0] == '/') {
57104
path_ = url_;

proxygen/lib/utils/ParseURL.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ class ParseURL {
4747
return ParseURL(urlVal, strict);
4848
}
4949

50+
static bool isSupportedScheme(const std::string& location);
51+
52+
static folly::Optional<std::string> getRedirectDestination(
53+
const std::string& url,
54+
const std::string& requestScheme,
55+
const std::string& location,
56+
const std::string& headerHost) noexcept;
57+
5058
// Deprecated. Will be removed soon
5159
explicit ParseURL(folly::StringPiece urlVal, bool strict = true) noexcept {
5260
init(urlVal, strict);

0 commit comments

Comments
 (0)