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 WorkerWebSocketExtension::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 WorkerWebSocketExtension::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 WorkerWebSocketExtension::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 Workerbool 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 Workerstd::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