summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/common/user_agent/user_agent_metadata.cc
blob: 9e104985bae2ad1bebe7e84049f3d0f62e255ad2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"

#include "base/pickle.h"
#include "net/http/structured_headers.h"

namespace blink {

namespace {
constexpr uint32_t kVersionUA = 2u;
}  // namespace

UserAgentBrandVersion::UserAgentBrandVersion(
    const std::string& ua_brand,
    const std::string& ua_major_version) {
  brand = ua_brand;
  major_version = ua_major_version;
}

const std::string UserAgentMetadata::SerializeBrandVersionList() {
  net::structured_headers::List brand_version_header =
      net::structured_headers::List();
  for (const UserAgentBrandVersion& brand_version : brand_version_list) {
    if (brand_version.major_version.empty()) {
      brand_version_header.push_back(
          net::structured_headers::ParameterizedMember(
              net::structured_headers::Item(brand_version.brand), {}));
    } else {
      brand_version_header.push_back(
          net::structured_headers::ParameterizedMember(
              net::structured_headers::Item(brand_version.brand),
              {std::make_pair("v", net::structured_headers::Item(
                                       brand_version.major_version))}));
    }
  }

  return net::structured_headers::SerializeList(brand_version_header)
      .value_or("");
}

// static
absl::optional<std::string> UserAgentMetadata::Marshal(
    const absl::optional<UserAgentMetadata>& in) {
  if (!in)
    return absl::nullopt;
  base::Pickle out;
  out.WriteUInt32(kVersionUA);

  out.WriteUInt32(in->brand_version_list.size());
  for (const auto& brand_version : in->brand_version_list) {
    out.WriteString(brand_version.brand);
    out.WriteString(brand_version.major_version);
  }

  out.WriteString(in->full_version);
  out.WriteString(in->platform);
  out.WriteString(in->platform_version);
  out.WriteString(in->architecture);
  out.WriteString(in->model);
  out.WriteBool(in->mobile);
  return std::string(reinterpret_cast<const char*>(out.data()), out.size());
}

// static
absl::optional<UserAgentMetadata> UserAgentMetadata::Demarshal(
    const absl::optional<std::string>& encoded) {
  if (!encoded)
    return absl::nullopt;

  base::Pickle pickle(encoded->data(), encoded->size());
  base::PickleIterator in(pickle);

  uint32_t version;
  UserAgentMetadata out;
  if (!in.ReadUInt32(&version) || version != kVersionUA)
    return absl::nullopt;

  uint32_t brand_version_size;
  if (!in.ReadUInt32(&brand_version_size))
    return absl::nullopt;
  for (uint32_t i = 0; i < brand_version_size; i++) {
    UserAgentBrandVersion brand_version;
    if (!in.ReadString(&brand_version.brand))
      return absl::nullopt;
    if (!in.ReadString(&brand_version.major_version))
      return absl::nullopt;
    out.brand_version_list.push_back(std::move(brand_version));
  }

  if (!in.ReadString(&out.full_version))
    return absl::nullopt;
  if (!in.ReadString(&out.platform))
    return absl::nullopt;
  if (!in.ReadString(&out.platform_version))
    return absl::nullopt;
  if (!in.ReadString(&out.architecture))
    return absl::nullopt;
  if (!in.ReadString(&out.model))
    return absl::nullopt;
  if (!in.ReadBool(&out.mobile))
    return absl::nullopt;
  return absl::make_optional(std::move(out));
}

bool UserAgentBrandVersion::operator==(const UserAgentBrandVersion& a) const {
  return a.brand == brand && a.major_version == major_version;
}

bool operator==(const UserAgentMetadata& a, const UserAgentMetadata& b) {
  return a.brand_version_list == b.brand_version_list &&
         a.full_version == b.full_version && a.platform == b.platform &&
         a.platform_version == b.platform_version &&
         a.architecture == b.architecture && a.model == b.model &&
         a.mobile == b.mobile;
}

bool operator==(const UserAgentOverride& a, const UserAgentOverride& b) {
  return a.ua_string_override == b.ua_string_override &&
         a.ua_metadata_override == b.ua_metadata_override;
}

}  // namespace blink