blob: 450c65dfc78171d679f4228b27386511a318fbd8 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "android_webview/browser/aw_origin_matched_header.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/scoped_refptr.h"
#include "components/origin_matcher/origin_matcher.h"
#include "third_party/jni_zero/jni_zero.h"
// Must come after all headers that specialize FromJniType() / ToJniType().
#include "android_webview/browser_jni_headers/AwOriginMatchedHeader_jni.h"
namespace android_webview {
AwOriginMatchedHeader::AwOriginMatchedHeader(
std::string name,
std::string value,
origin_matcher::OriginMatcher origin_matcher)
: name_(std::move(name)),
value_(std::move(value)),
matcher_(std::move(origin_matcher)) {}
AwOriginMatchedHeader::~AwOriginMatchedHeader() = default;
bool AwOriginMatchedHeader::MatchesOrigin(const url::Origin& origin) const {
return matcher_.Matches(origin);
}
scoped_refptr<AwOriginMatchedHeader> AwOriginMatchedHeader::MergedWithMatcher(
origin_matcher::OriginMatcher&& other) const {
std::vector<std::string> new_rules = other.Serialize();
// Use a set to avoid linear lookups in `new_rules`.
base::flat_set<std::string_view> new_rules_set(new_rules.begin(),
new_rules.end());
// Merge the existing rules into the new matcher without duplicates.
std::vector<std::string> existing_rules = matcher_.Serialize();
for (const std::string& existing_rule : existing_rules) {
if (!new_rules_set.contains(existing_rule)) {
other.AddRuleFromString(existing_rule);
}
}
return base::MakeRefCounted<AwOriginMatchedHeader>(name_, value_,
std::move(other));
}
// static
base::flat_map<std::string_view, std::string>
AwOriginMatchedHeader::GetCombinedMatchingHeaders(
base::span<scoped_refptr<AwOriginMatchedHeader>> headers,
const url::Origin& origin) {
base::flat_map<std::string_view, std::string> combined_headers;
for (const auto& header : headers) {
if (!header->MatchesOrigin(origin)) {
continue;
}
auto combined_itr = combined_headers.find(header->name());
if (combined_itr == combined_headers.end()) {
combined_headers.emplace(header->name(), header->value());
} else {
combined_itr->second.append(",");
combined_itr->second.append(header->value());
}
}
return combined_headers;
}
bool AwOriginMatchedHeader::MatchesNameValue(
const std::string& target_name,
const std::optional<std::string>& target_value) const {
if (name_ != target_name) {
return false;
}
if (!target_value) {
return true;
}
return value_ == *target_value;
}
jni_zero::ScopedJavaLocalRef<jobject> AwOriginMatchedHeader::ToJavaObject(
JNIEnv* env) {
return Java_AwOriginMatchedHeader_create(env, name_, value_,
matcher_.Serialize());
}
} // namespace android_webview