Skip to content

Commit

Permalink
Added veryfication if path contains query params and add them to path…
Browse files Browse the repository at this point in the history
… header (#6466)

* Description: Added veryfication if path contains query params and append path headers if it has them
Risk Level: medium (affects data plane, if only for fully qualified urls)
Testing: added new test cases
Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Lukasz Dziedziak <lukasz.dziedziak@allegro.pl>
  • Loading branch information
lukidzi authored and alyssawilk committed Apr 4, 2019
1 parent b84c1f9 commit 1cf59d4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion source/common/http/http1/codec_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ void ServerConnectionImpl::handlePath(HeaderMapImpl& headers, unsigned int metho
// forward the received Host field-value.
headers.insertHost().value(std::string(absolute_url.host_and_port()));

headers.insertPath().value(std::string(absolute_url.path()));
headers.insertPath().value(std::string(absolute_url.path_and_query_params()));
active_request_->request_url_.clear();
}

Expand Down
15 changes: 12 additions & 3 deletions source/common/http/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,19 @@ bool Utility::Url::initialize(absl::string_view absolute_url) {
// RFC allows the absolute-uri to not end in /, but the absolute path form
// must start with
if ((u.field_set & (1 << UF_PATH)) == (1 << UF_PATH) && u.field_data[UF_PATH].len > 0) {
path_ = absl::string_view(absolute_url.data() + u.field_data[UF_PATH].off,
u.field_data[UF_PATH].len);
uint64_t path_len = u.field_data[UF_PATH].len;
if ((u.field_set & (1 << UF_QUERY)) == (1 << UF_QUERY) && u.field_data[UF_QUERY].len > 0) {
path_len += 1 + u.field_data[UF_QUERY].len;
}
path_and_query_params_ =
absl::string_view(absolute_url.data() + u.field_data[UF_PATH].off, path_len);
} else if ((u.field_set & (1 << UF_QUERY)) == (1 << UF_QUERY) && u.field_data[UF_QUERY].len > 0) {
// Http parser skips question mark and starts count from first character after ?
// so we need to move left by one
path_and_query_params_ = absl::string_view(absolute_url.data() + u.field_data[UF_QUERY].off - 1,
u.field_data[UF_QUERY].len + 1);
} else {
path_ = absl::string_view(kDefaultPath, 1);
path_and_query_params_ = absl::string_view(kDefaultPath, 1);
}
return true;
}
Expand Down
6 changes: 3 additions & 3 deletions source/common/http/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ namespace Utility {

/**
* Given a fully qualified URL, splits the string_view provided into scheme,
* host and path components.
* host and path with query parameters components.
*/
class Url {
public:
bool initialize(absl::string_view absolute_url);
absl::string_view scheme() { return scheme_; }
absl::string_view host_and_port() { return host_and_port_; }
absl::string_view path() { return path_; }
absl::string_view path_and_query_params() { return path_and_query_params_; }

private:
absl::string_view scheme_;
absl::string_view host_and_port_;
absl::string_view path_;
absl::string_view path_and_query_params_;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion source/common/router/router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ bool convertRequestHeadersForInternalRedirect(Http::HeaderMap& downstream_header
// Replace the original host, scheme and path.
downstream_headers.insertScheme().value(std::string(absolute_url.scheme()));
downstream_headers.insertHost().value(std::string(absolute_url.host_and_port()));
downstream_headers.insertPath().value(std::string(absolute_url.path()));
downstream_headers.insertPath().value(std::string(absolute_url.path_and_query_params()));

return true;
}
Expand Down
33 changes: 32 additions & 1 deletion test/common/http/utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ void ValidateUrl(absl::string_view raw_url, absl::string_view expected_scheme,
ASSERT_TRUE(url.initialize(raw_url)) << "Failed to initialize " << raw_url;
EXPECT_EQ(url.scheme(), expected_scheme);
EXPECT_EQ(url.host_and_port(), expected_host_port);
EXPECT_EQ(url.path(), expected_path);
EXPECT_EQ(url.path_and_query_params(), expected_path);
}

TEST(Url, ParsingTest) {
Expand All @@ -766,12 +766,43 @@ TEST(Url, ParsingTest) {
ValidateUrl("http://www.host.com:80/", "http", "www.host.com:80", "/");
ValidateUrl("http://www.host.com/", "http", "www.host.com", "/");

// Test url with "?".
ValidateUrl("http://www.host.com:80/?", "http", "www.host.com:80", "/");
ValidateUrl("http://www.host.com/?", "http", "www.host.com", "/");

// Test url with "?" but without slash.
ValidateUrl("http://www.host.com:80?", "http", "www.host.com:80", "/");
ValidateUrl("http://www.host.com?", "http", "www.host.com", "/");

// Test url with multi-character path
ValidateUrl("http://www.host.com:80/path", "http", "www.host.com:80", "/path");
ValidateUrl("http://www.host.com/path", "http", "www.host.com", "/path");

// Test url with multi-character path and ? at the end
ValidateUrl("http://www.host.com:80/path?", "http", "www.host.com:80", "/path");
ValidateUrl("http://www.host.com/path?", "http", "www.host.com", "/path");

// Test https scheme
ValidateUrl("https://www.host.com", "https", "www.host.com", "/");

// Test url with query parameter
ValidateUrl("http://www.host.com:80/?query=param", "http", "www.host.com:80", "/?query=param");
ValidateUrl("http://www.host.com/?query=param", "http", "www.host.com", "/?query=param");

// Test url with query parameter but without slash
ValidateUrl("http://www.host.com:80?query=param", "http", "www.host.com:80", "?query=param");
ValidateUrl("http://www.host.com?query=param", "http", "www.host.com", "?query=param");

// Test url with multi-character path and query parameter
ValidateUrl("http://www.host.com:80/path?query=param", "http", "www.host.com:80",
"/path?query=param");
ValidateUrl("http://www.host.com/path?query=param", "http", "www.host.com", "/path?query=param");

// Test url with multi-character path and more than one query parameter
ValidateUrl("http://www.host.com:80/path?query=param&query2=param2", "http", "www.host.com:80",
"/path?query=param&query2=param2");
ValidateUrl("http://www.host.com/path?query=param&query2=param2", "http", "www.host.com",
"/path?query=param&query2=param2");
}

} // namespace Http
Expand Down

0 comments on commit 1cf59d4

Please sign in to comment.