1 // Copyright 2021 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/base/connection_endpoint_metadata.h" 6 7 #include <optional> 8 #include <string> 9 #include <utility> 10 #include <vector> 11 12 #include "base/base64.h" 13 #include "base/values.h" 14 15 namespace net { 16 17 namespace { 18 const char kSupportedProtocolAlpnsKey[] = "supported_protocol_alpns"; 19 const char kEchConfigListKey[] = "ech_config_list"; 20 const char kTargetNameKey[] = "target_name"; 21 } // namespace 22 23 ConnectionEndpointMetadata::ConnectionEndpointMetadata() = default; 24 ConnectionEndpointMetadata(std::vector<std::string> supported_protocol_alpns,EchConfigList ech_config_list,std::string target_name)25ConnectionEndpointMetadata::ConnectionEndpointMetadata( 26 std::vector<std::string> supported_protocol_alpns, 27 EchConfigList ech_config_list, 28 std::string target_name) 29 : supported_protocol_alpns(std::move(supported_protocol_alpns)), 30 ech_config_list(std::move(ech_config_list)), 31 target_name(std::move(target_name)) {} 32 33 ConnectionEndpointMetadata::~ConnectionEndpointMetadata() = default; 34 ConnectionEndpointMetadata::ConnectionEndpointMetadata( 35 const ConnectionEndpointMetadata&) = default; 36 ConnectionEndpointMetadata::ConnectionEndpointMetadata( 37 ConnectionEndpointMetadata&&) = default; 38 ToValue() const39base::Value ConnectionEndpointMetadata::ToValue() const { 40 base::Value::Dict dict; 41 42 base::Value::List alpns_list; 43 for (const std::string& alpn : supported_protocol_alpns) { 44 alpns_list.Append(alpn); 45 } 46 dict.Set(kSupportedProtocolAlpnsKey, std::move(alpns_list)); 47 48 dict.Set(kEchConfigListKey, base::Base64Encode(ech_config_list)); 49 50 if (!target_name.empty()) { 51 dict.Set(kTargetNameKey, target_name); 52 } 53 54 return base::Value(std::move(dict)); 55 } 56 57 // static FromValue(const base::Value & value)58std::optional<ConnectionEndpointMetadata> ConnectionEndpointMetadata::FromValue( 59 const base::Value& value) { 60 const base::Value::Dict* dict = value.GetIfDict(); 61 if (!dict) 62 return std::nullopt; 63 64 const base::Value::List* alpns_list = 65 dict->FindList(kSupportedProtocolAlpnsKey); 66 const std::string* ech_config_list_value = 67 dict->FindString(kEchConfigListKey); 68 const std::string* target_name_value = dict->FindString(kTargetNameKey); 69 70 if (!alpns_list || !ech_config_list_value) 71 return std::nullopt; 72 73 ConnectionEndpointMetadata metadata; 74 75 std::vector<std::string> alpns; 76 for (const base::Value& alpn : *alpns_list) { 77 if (!alpn.is_string()) 78 return std::nullopt; 79 metadata.supported_protocol_alpns.push_back(alpn.GetString()); 80 } 81 82 std::optional<std::vector<uint8_t>> decoded = 83 base::Base64Decode(*ech_config_list_value); 84 if (!decoded) 85 return std::nullopt; 86 metadata.ech_config_list = std::move(*decoded); 87 88 if (target_name_value) { 89 metadata.target_name = *target_name_value; 90 } 91 92 return metadata; 93 } 94 95 } // namespace net 96