1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/url_request/referrer_policy.h"
6
7 #include <string>
8
9 #include "base/containers/adapters.h"
10 #include "base/containers/fixed_flat_map.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h"
13
14 namespace net {
15
ReferrerPolicyFromHeader(std::string_view referrer_policy_header_value)16 std::optional<ReferrerPolicy> ReferrerPolicyFromHeader(
17 std::string_view referrer_policy_header_value) {
18 using enum ReferrerPolicy;
19 const auto policy_tokens =
20 base::SplitStringPiece(referrer_policy_header_value, ",",
21 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
22
23 // Map from lower-cased token to ReferrerPolicy. It's good for compile speed
24 // to keep this sorted.
25 static constexpr auto kTokenToReferrerPolicy =
26 base::MakeFixedFlatMap<std::string_view, ReferrerPolicy>(
27 {{"no-referrer", NO_REFERRER},
28 {"no-referrer-when-downgrade",
29 CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE},
30 {"origin", ORIGIN},
31 {"origin-when-cross-origin", ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN},
32 {"same-origin", CLEAR_ON_TRANSITION_CROSS_ORIGIN},
33 {"strict-origin",
34 ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE},
35 {"strict-origin-when-cross-origin",
36 REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN},
37 {"unsafe-url", NEVER_CLEAR}});
38
39 // Per https://w3c.github.io/webappsec-referrer-policy/#unknown-policy-values,
40 // use the last recognized policy value, and ignore unknown policies.
41 for (const auto& token : base::Reversed(policy_tokens)) {
42 const std::string lowered_token = base::ToLowerASCII(token);
43 const auto it = kTokenToReferrerPolicy.find(lowered_token);
44 if (it != kTokenToReferrerPolicy.end()) {
45 return it->second;
46 }
47 }
48
49 return std::nullopt;
50 }
51
52 } // namespace net
53