blob: b32b864b8004706c42e2a4797d633f0c33ef6bcb [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/public/cpp/document_isolation_policy_parser.h"
#include <algorithm>
#include <optional>
#include <string_view>
#include <utility>
#include "net/http/http_response_headers.h"
#include "net/http/structured_headers.h"
#include "services/network/public/cpp/document_isolation_policy.h"
namespace network {
namespace {
constexpr char kHeaderName[] = "document-isolation-policy";
constexpr char kReportOnlyHeaderName[] =
"document-isolation-policy-report-only";
std::pair<mojom::DocumentIsolationPolicyValue, std::optional<std::string>>
Parse(std::string_view header_value) {
using Item = net::structured_headers::Item;
const auto item = net::structured_headers::ParseItem(header_value);
if (!item || item->item.Type() != net::structured_headers::Item::kTokenType) {
return {
mojom::DocumentIsolationPolicyValue::kNone,
std::nullopt,
};
}
std::optional<std::string> endpoint;
for (const auto& it : item->params) {
if (it.first == "report-to" && it.second.Type() == Item::kStringType) {
endpoint = it.second.GetString();
}
}
if (item->item.GetString() == "isolate-and-require-corp") {
return {
mojom::DocumentIsolationPolicyValue::kIsolateAndRequireCorp,
std::move(endpoint),
};
}
if (item->item.GetString() == "isolate-and-credentialless") {
return {
mojom::DocumentIsolationPolicyValue::kIsolateAndCredentialless,
std::move(endpoint),
};
}
return {
mojom::DocumentIsolationPolicyValue::kNone,
std::nullopt,
};
}
} // namespace
DocumentIsolationPolicy ParseDocumentIsolationPolicy(
const net::HttpResponseHeaders& headers) {
DocumentIsolationPolicy dip;
if (std::optional<std::string> header_value =
headers.GetNormalizedHeader(kHeaderName)) {
std::tie(dip.value, dip.reporting_endpoint) = Parse(*header_value);
}
if (std::optional<std::string> header_value =
headers.GetNormalizedHeader(kReportOnlyHeaderName)) {
std::tie(dip.report_only_value, dip.report_only_reporting_endpoint) =
Parse(*header_value);
}
return dip;
}
} // namespace network