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