• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 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/proxy_chain.h"
6 
7 #include <ostream>
8 #include <vector>
9 
10 #include "base/check.h"
11 #include "base/no_destructor.h"
12 #include "net/base/proxy_string_util.h"
13 
14 namespace net {
15 
ProxyChain()16 ProxyChain::ProxyChain() {
17   proxy_server_list_ = std::nullopt;
18 }
19 
20 ProxyChain::ProxyChain(const ProxyChain& other) = default;
21 ProxyChain::ProxyChain(ProxyChain&& other) noexcept = default;
22 
23 ProxyChain& ProxyChain::operator=(const ProxyChain& other) = default;
24 ProxyChain& ProxyChain::operator=(ProxyChain&& other) noexcept = default;
25 
26 ProxyChain::~ProxyChain() = default;
27 
28 // TODO(crbug.com/1491092): Remove is_direct() check when
29 // ProxyServer::SCHEME_DIRECT is deprecated.
ProxyChain(ProxyServer proxy_server)30 ProxyChain::ProxyChain(ProxyServer proxy_server)
31     : ProxyChain(!proxy_server.is_direct()
32                      ? std::vector<ProxyServer>{std::move(proxy_server)}
33                      : std::vector<ProxyServer>()) {}
34 
ProxyChain(ProxyServer::Scheme scheme,const HostPortPair & host_port_pair)35 ProxyChain::ProxyChain(ProxyServer::Scheme scheme,
36                        const HostPortPair& host_port_pair)
37     : ProxyChain({ProxyServer(scheme, host_port_pair)}) {}
38 
ProxyChain(std::vector<ProxyServer> proxy_server_list)39 ProxyChain::ProxyChain(std::vector<ProxyServer> proxy_server_list)
40     : proxy_server_list_(std::move(proxy_server_list)) {
41   if (!IsValidInternal()) {
42     proxy_server_list_ = std::nullopt;
43   }
44 }
45 
GetProxyServer(size_t chain_index) const46 const ProxyServer& ProxyChain::GetProxyServer(size_t chain_index) const {
47   DCHECK(IsValid());
48   CHECK_LT(chain_index, proxy_server_list_.value().size());
49   return proxy_server_list_.value().at(chain_index);
50 }
51 
proxy_servers() const52 const std::vector<ProxyServer>& ProxyChain::proxy_servers() const {
53   DCHECK(IsValid());
54   return proxy_server_list_.value();
55 }
56 
proxy_server() const57 const ProxyServer& ProxyChain::proxy_server() const {
58   if (!proxy_server_list_.has_value()) {
59     static base::NoDestructor<ProxyServer> invalid(ProxyServer::SCHEME_INVALID,
60                                                    HostPortPair());
61     return *invalid;
62   } else if (proxy_server_list_.value().empty()) {
63     static base::NoDestructor<ProxyServer> direct(ProxyServer::SCHEME_DIRECT,
64                                                   HostPortPair());
65     return *direct;
66   }
67   CHECK_EQ(1u, proxy_server_list_->size())
68       << "Cannot call `proxy_server() on a ProxyChain with multiple proxies: "
69       << ToDebugString();
70   return proxy_server_list_.value().at(0);
71 }
72 
ToDebugString() const73 std::string ProxyChain::ToDebugString() const {
74   if (!IsValid()) {
75     return "INVALID PROXY CHAIN";
76   }
77   std::string debug_string =
78       proxy_server_list_.value().empty() ? "direct://" : "";
79   for (const ProxyServer& proxy_server : proxy_server_list_.value()) {
80     if (!debug_string.empty()) {
81       debug_string += ", ";
82     }
83     debug_string += ProxyServerToProxyUri(proxy_server);
84   }
85   return "[" + debug_string + "]";
86 }
87 
88 // TODO(crbug.com/1491092): Remove is_direct() checks when
89 // ProxyServer::SCHEME_DIRECT is deprecated.
IsValidInternal() const90 bool ProxyChain::IsValidInternal() const {
91   if (!proxy_server_list_.has_value()) {
92     return false;
93   }
94   if (is_single_proxy()) {
95     return proxy_server_list_.value().at(0).is_valid() &&
96            !proxy_server_list_.value().at(0).is_direct();
97   }
98   for (const auto& proxy_server : proxy_server_list_.value()) {
99     if (!proxy_server.is_valid() || !proxy_server.is_https() ||
100         proxy_server.is_direct()) {
101       return false;
102     }
103   }
104   return true;
105 }
106 
operator <<(std::ostream & os,const ProxyChain & proxy_chain)107 std::ostream& operator<<(std::ostream& os, const ProxyChain& proxy_chain) {
108   return os << proxy_chain.ToDebugString();
109 }
110 
111 }  // namespace net
112