• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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