mirror of
https://github.com/alibaba/higress.git
synced 2026-06-09 12:47:28 +08:00
wasm: strip port from host when match host (#626)
This commit is contained in:
@@ -387,6 +387,8 @@ class RouteRuleMatcher {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_host = Wasm::Common::Http::stripPortFromHost(request_host);
|
||||||
|
|
||||||
for (const auto& host_match : rule.hosts) {
|
for (const auto& host_match : rule.hosts) {
|
||||||
const auto& host = host_match.second;
|
const auto& host = host_match.second;
|
||||||
switch (host_match.first) {
|
switch (host_match.first) {
|
||||||
|
|||||||
@@ -584,6 +584,48 @@ TEST_F(BasicAuthTest, RuleWithConsumerAllow) {
|
|||||||
FilterHeadersStatus::Continue);
|
FilterHeadersStatus::Continue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BasicAuthTest, GlobalAuthRuleWithDomainPort) {
|
||||||
|
std::string configuration = R"(
|
||||||
|
{
|
||||||
|
"global_auth": true,
|
||||||
|
"consumers" : [
|
||||||
|
{"credential" : "ok:test", "name" : "consumer_ok"},
|
||||||
|
{"credential" : "admin2:admin2", "name" : "consumer2"},
|
||||||
|
{"credential" : "YWRtaW4zOmFkbWluMw==", "name" : "consumer3"},
|
||||||
|
{"credential" : "admin:admin", "name" : "consumer"}
|
||||||
|
],
|
||||||
|
"_rules_" : [
|
||||||
|
{
|
||||||
|
"_match_domain_" : ["test.com", "*.example.com"],
|
||||||
|
"allow" : [ "consumer" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})";
|
||||||
|
|
||||||
|
BufferBase buffer;
|
||||||
|
buffer.set({configuration.data(), configuration.size()});
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_context_, getBuffer(WasmBufferType::PluginConfiguration))
|
||||||
|
.WillOnce([&buffer](WasmBufferType) { return &buffer; });
|
||||||
|
EXPECT_TRUE(root_context_->configure(configuration.size()));
|
||||||
|
|
||||||
|
authority_ = "www.example.com:8080";
|
||||||
|
cred_ = "admin:admin";
|
||||||
|
authorization_header_ = "Basic " + Base64::encode(cred_.data(), cred_.size());
|
||||||
|
EXPECT_EQ(context_->onRequestHeaders(0, false),
|
||||||
|
FilterHeadersStatus::Continue);
|
||||||
|
|
||||||
|
cred_ = "admin2:admin2";
|
||||||
|
authorization_header_ = "Basic " + Base64::encode(cred_.data(), cred_.size());
|
||||||
|
EXPECT_EQ(context_->onRequestHeaders(0, false),
|
||||||
|
FilterHeadersStatus::StopIteration);
|
||||||
|
|
||||||
|
authority_ = "abc.com";
|
||||||
|
authorization_header_ = "Basic " + Base64::encode(cred_.data(), cred_.size());
|
||||||
|
EXPECT_EQ(context_->onRequestHeaders(0, false),
|
||||||
|
FilterHeadersStatus::Continue);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BasicAuthTest, RuleWithEncryptedConsumerAllow) {
|
TEST_F(BasicAuthTest, RuleWithEncryptedConsumerAllow) {
|
||||||
std::string configuration = R"(
|
std::string configuration = R"(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ func (m *RuleMatcher[PluginConfig]) ParseRuleConfig(config gjson.Result,
|
|||||||
if keyCount > 0 {
|
if keyCount > 0 {
|
||||||
err := parsePluginConfig(config, &pluginConfig)
|
err := parsePluginConfig(config, &pluginConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
proxywasm.LogWarnf("parse global config failed, err:%v", err)
|
|
||||||
globalConfigError = err
|
globalConfigError = err
|
||||||
} else {
|
} else {
|
||||||
m.globalConfig = pluginConfig
|
m.globalConfig = pluginConfig
|
||||||
@@ -185,7 +184,25 @@ func (m RuleMatcher[PluginConfig]) parseHostMatchConfig(config gjson.Result) []H
|
|||||||
return hostMatchers
|
return hostMatchers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stripPortFromHost(reqHost string) string {
|
||||||
|
// Port removing code is inspired by
|
||||||
|
// https://github.com/envoyproxy/envoy/blob/v1.17.0/source/common/http/header_utility.cc#L219
|
||||||
|
portStart := strings.LastIndexByte(reqHost, ':')
|
||||||
|
if portStart != -1 {
|
||||||
|
// According to RFC3986 v6 address is always enclosed in "[]".
|
||||||
|
// section 3.2.2.
|
||||||
|
v6EndIndex := strings.LastIndexByte(reqHost, ']')
|
||||||
|
if v6EndIndex == -1 || v6EndIndex < portStart {
|
||||||
|
if portStart+1 <= len(reqHost) {
|
||||||
|
return reqHost[:portStart]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reqHost
|
||||||
|
}
|
||||||
|
|
||||||
func (m RuleMatcher[PluginConfig]) hostMatch(rule RuleConfig[PluginConfig], reqHost string) bool {
|
func (m RuleMatcher[PluginConfig]) hostMatch(rule RuleConfig[PluginConfig], reqHost string) bool {
|
||||||
|
reqHost = stripPortFromHost(reqHost)
|
||||||
for _, hostMatch := range rule.hosts {
|
for _, hostMatch := range rule.hosts {
|
||||||
switch hostMatch.matchType {
|
switch hostMatch.matchType {
|
||||||
case Suffix:
|
case Suffix:
|
||||||
|
|||||||
@@ -118,6 +118,19 @@ func TestHostMatch(t *testing.T) {
|
|||||||
host: "example.com",
|
host: "example.com",
|
||||||
result: false,
|
result: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "exact port",
|
||||||
|
config: RuleConfig[customConfig]{
|
||||||
|
hosts: []HostMatcher{
|
||||||
|
{
|
||||||
|
matchType: Exact,
|
||||||
|
host: "www.example.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
host: "www.example.com:8080",
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "any",
|
name: "any",
|
||||||
config: RuleConfig[customConfig]{
|
config: RuleConfig[customConfig]{
|
||||||
|
|||||||
Reference in New Issue
Block a user