• 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 #ifndef NET_BASE_PROXY_CHAIN_H_
6 #define NET_BASE_PROXY_CHAIN_H_
7 
8 #include <stdint.h>
9 
10 #include <optional>
11 #include <ostream>
12 #include <string>
13 #include <string_view>
14 #include <tuple>
15 #include <vector>
16 
17 #include "net/base/host_port_pair.h"
18 #include "net/base/net_export.h"
19 #include "net/base/proxy_server.h"
20 
21 namespace net {
22 
23 // ProxyChain represents a chain of ProxyServers. A chain with multiple proxy
24 // servers means that a single connection will go through all of the proxies in
25 // order, using a tunnel through the first proxy to connect to the second, etc.
26 // A "direct" connection is a chain of length zero.
27 //
28 // TODO(crbug.com/1491092): Initial implementations of proxy chaining may, in
29 // fact, not tunnel through the last proxy in the ProxyChain if the destination
30 // is http.
31 class NET_EXPORT ProxyChain {
32  public:
33   // Constructs an invalid ProxyChain.
34   ProxyChain();
35 
36   ProxyChain(const ProxyChain& other);      // Copy constructor
37   ProxyChain(ProxyChain&& other) noexcept;  // Move constructor
38 
39   ProxyChain& operator=(const ProxyChain& other);  // Copy assignment operator
40   ProxyChain& operator=(
41       ProxyChain&& other) noexcept;  // Move assignment operator
42 
43   ProxyChain(ProxyServer::Scheme scheme, const HostPortPair& host_port_pair);
44 
45   explicit ProxyChain(std::vector<ProxyServer> proxy_server_list);
46   explicit ProxyChain(ProxyServer proxy_server);
47 
48   ~ProxyChain();  // Destructor declaration
49 
50   // Creates a single-proxy ProxyChain, validating and canonicalizing input.
51   // Port is optional and, if not provided, will be replaced with the default
52   // port for the given scheme. Accepts IPv6 literal `host`s with surrounding
53   // brackets (URL format) or without (HostPortPair format). On invalid input,
54   // result will be a `SCHEME_INVALID` ProxyChain.
55   //
56   // Must not be called with `SCHEME_INVALID` or `SCHEME_DIRECT`. Use
57   // `ProxyChain()` or `Direct()` respectively to create an invalid or direct
58   // ProxyChain.
FromSchemeHostAndPort(ProxyServer::Scheme scheme,std::string_view host,std::string_view port_str)59   static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
60                                           std::string_view host,
61                                           std::string_view port_str) {
62     return ProxyChain(
63         ProxyServer::FromSchemeHostAndPort(scheme, host, port_str));
64   }
FromSchemeHostAndPort(ProxyServer::Scheme scheme,std::string_view host,std::optional<uint16_t> port)65   static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
66                                           std::string_view host,
67                                           std::optional<uint16_t> port) {
68     return ProxyChain(ProxyServer::FromSchemeHostAndPort(scheme, host, port));
69   }
70   // Create a "direct" proxy chain, which includes no proxy servers.
Direct()71   static ProxyChain Direct() { return ProxyChain(ProxyServer::Direct()); }
72 
73   // Get ProxyServer at index in chain. This is not valid for direct or invalid
74   // proxy chains.
75   const ProxyServer& GetProxyServer(size_t chain_index) const;
76 
77   // Get the ProxyServers in this chain. This must not be called on invalid
78   // proxy chains. An empty vector is returned for direct proxy chains.
79   const std::vector<ProxyServer>& proxy_servers() const;
80 
81   // Get the ProxyServers in this chain, or `nullopt` if the chain is not valid.
proxy_servers_if_valid()82   const std::optional<std::vector<ProxyServer>>& proxy_servers_if_valid()
83       const {
84     return proxy_server_list_;
85   }
86 
87   // Get the single ProxyServer equivalent to this chain. This must not be
88   // called for multi-proxy chains.
89   // TODO(crbug.com/1491092): Remove this method.
90   const ProxyServer& proxy_server() const;
91 
92   // Returns number of proxy servers in chain.
length()93   size_t length() const {
94     return proxy_server_list_.has_value() ? proxy_server_list_.value().size()
95                                           : 0;
96   }
97 
98   // Returns true if this chain contains more than one proxy.
is_multi_proxy()99   bool is_multi_proxy() const {
100     return proxy_server_list_.has_value()
101                ? proxy_server_list_.value().size() > 1
102                : false;
103   }
104 
105   // Returns true if this chain contains exactly one proxy.
is_single_proxy()106   bool is_single_proxy() const {
107     return proxy_server_list_.has_value()
108                ? proxy_server_list_.value().size() == 1
109                : false;
110   }
111 
112   // Returns true if this is a direct (equivalently, zero-proxy) chain.
is_direct()113   bool is_direct() const {
114     return proxy_server_list_.has_value() ? proxy_server_list_.value().empty()
115                                           : false;
116   }
117 
118   // Returns true if a proxy server list is available .
IsValid()119   bool IsValid() const { return proxy_server_list_.has_value(); }
120 
121   bool operator==(const ProxyChain& other) const {
122     return proxy_server_list_ == other.proxy_server_list_;
123   }
124 
125   bool operator!=(const ProxyChain& other) const { return !(*this == other); }
126 
127   // Comparator function so this can be placed in a std::map.
128   bool operator<(const ProxyChain& other) const {
129     return proxy_server_list_ < other.proxy_server_list_;
130   }
131 
132   std::string ToDebugString() const;
133 
134  private:
135   std::optional<std::vector<ProxyServer>> proxy_server_list_;
136 
137   // Returns true if this chain is valid.
138   bool IsValidInternal() const;
139 };
140 
141 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
142                                             const ProxyChain& proxy_chain);
143 
144 // A HostPortProxyPair holds a host/port destination and a ProxyChain describing
145 // how that destination is reached.
146 typedef std::pair<HostPortPair, ProxyChain> HostPortProxyPair;
147 
148 }  // namespace net
149 
150 #endif  // NET_BASE_PROXY_CHAIN_H_
151