xref: /aosp_15_r20/external/cronet/net/websockets/websocket_extension.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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/websockets/websocket_extension.h"
6 
7 #include <map>
8 #include <string>
9 #include <utility>
10 
11 #include "base/check.h"
12 #include "base/ranges/algorithm.h"
13 #include "net/http/http_util.h"
14 
15 namespace net {
16 
Parameter(const std::string & name)17 WebSocketExtension::Parameter::Parameter(const std::string& name)
18     : name_(name) {}
19 
Parameter(const std::string & name,const std::string & value)20 WebSocketExtension::Parameter::Parameter(const std::string& name,
21                                          const std::string& value)
22     : name_(name), value_(value) {
23   DCHECK(!value.empty());
24   // |extension-param| must be a token.
25   DCHECK(HttpUtil::IsToken(value));
26 }
27 
28 bool WebSocketExtension::Parameter::operator==(const Parameter& other) const =
29     default;
30 
31 WebSocketExtension::WebSocketExtension() = default;
32 
WebSocketExtension(const std::string & name)33 WebSocketExtension::WebSocketExtension(const std::string& name)
34     : name_(name) {}
35 
36 WebSocketExtension::WebSocketExtension(const WebSocketExtension& other) =
37     default;
38 
39 WebSocketExtension::~WebSocketExtension() = default;
40 
Equivalent(const WebSocketExtension & other) const41 bool WebSocketExtension::Equivalent(const WebSocketExtension& other) const {
42   if (name_ != other.name_) return false;
43   if (parameters_.size() != other.parameters_.size()) return false;
44 
45   // Take copies in order to sort.
46   std::vector<Parameter> mine_sorted = parameters_;
47   std::vector<Parameter> other_sorted = other.parameters_;
48 
49   auto comparator = std::less<std::string>();
50   auto extract_name = [](const Parameter& param) { return param.name(); };
51   // Sort by key, preserving order of values.
52   base::ranges::stable_sort(mine_sorted, comparator, extract_name);
53   base::ranges::stable_sort(other_sorted, comparator, extract_name);
54 
55   return mine_sorted == other_sorted;
56 }
57 
ToString() const58 std::string WebSocketExtension::ToString() const {
59   if (name_.empty())
60     return std::string();
61 
62   std::string result = name_;
63 
64   for (const auto& param : parameters_) {
65     result += "; " + param.name();
66     if (!param.HasValue())
67       continue;
68 
69     // |extension-param| must be a token and we don't need to quote it.
70     DCHECK(HttpUtil::IsToken(param.value()));
71     result += "=" + param.value();
72   }
73   return result;
74 }
75 
76 }  // namespace net
77