1 // Copyright 2011 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_SERVER_H_ 6 #define NET_BASE_PROXY_SERVER_H_ 7 8 #include <stdint.h> 9 10 #include <ostream> 11 #include <string> 12 #include <tuple> 13 14 #include "base/strings/string_piece.h" 15 #include "net/base/host_port_pair.h" 16 #include "net/base/net_export.h" 17 #include "third_party/abseil-cpp/absl/types/optional.h" 18 19 namespace net { 20 21 // ProxyServer encodes the {type, host, port} of a proxy server. 22 // ProxyServer is immutable. 23 class NET_EXPORT ProxyServer { 24 public: 25 // The type of proxy. These are defined as bit flags so they can be ORed 26 // together to pass as the |scheme_bit_field| argument to 27 // ProxyList::RemoveProxiesWithoutScheme(). 28 enum Scheme { 29 SCHEME_INVALID = 1 << 0, 30 SCHEME_DIRECT = 1 << 1, 31 SCHEME_HTTP = 1 << 2, 32 SCHEME_SOCKS4 = 1 << 3, 33 SCHEME_SOCKS5 = 1 << 4, 34 SCHEME_HTTPS = 1 << 5, 35 // A QUIC proxy is an HTTP proxy in which QUIC is used as the transport, 36 // instead of TCP. 37 SCHEME_QUIC = 1 << 6, 38 }; 39 40 // Default copy-constructor and assignment operator are OK! 41 42 // Constructs an invalid ProxyServer. 43 ProxyServer() = default; 44 45 ProxyServer(Scheme scheme, const HostPortPair& host_port_pair); 46 47 // Creates a ProxyServer, validating and canonicalizing input. Port is 48 // optional and, if not provided, will be replaced with the default port for 49 // the given scheme. Accepts IPv6 literal `host`s with surrounding brackets 50 // (URL format) or without (HostPortPair format). On invalid input, result 51 // will be a `SCHEME_INVALID` ProxyServer. 52 // 53 // Must not be called with `SCHEME_INVALID` or `SCHEME_DIRECT`. Use 54 // `ProxyServer()` or `Direct()` respectively to create an invalid or direct 55 // ProxyServer. 56 static ProxyServer FromSchemeHostAndPort(Scheme scheme, 57 base::StringPiece host, 58 base::StringPiece port_str); 59 static ProxyServer FromSchemeHostAndPort(Scheme scheme, 60 base::StringPiece host, 61 absl::optional<uint16_t> port); 62 63 // In URL format (with brackets around IPv6 literals). Must not call for 64 // ProxyServers without a host (invalid or direct). 65 std::string GetHost() const; 66 67 // Must not call for ProxyServers without a host (invalid or direct). 68 uint16_t GetPort() const; 69 is_valid()70 bool is_valid() const { return scheme_ != SCHEME_INVALID; } 71 72 // Gets the proxy's scheme (i.e. SOCKS4, SOCKS5, HTTP) scheme()73 Scheme scheme() const { return scheme_; } 74 75 // Returns true if this ProxyServer is actually just a DIRECT connection. is_direct()76 bool is_direct() const { return scheme_ == SCHEME_DIRECT; } 77 78 // Returns true if this ProxyServer is an HTTP proxy. is_http()79 bool is_http() const { return scheme_ == SCHEME_HTTP; } 80 81 // Returns true if this ProxyServer is an HTTPS proxy. Note this 82 // does not include proxies matched by |is_quic()|. 83 // 84 // Generally one should test the more general concept of 85 // |is_secure_http_like()| to account for |is_quic()|. is_https()86 bool is_https() const { return scheme_ == SCHEME_HTTPS; } 87 88 // Returns true if this ProxyServer is a SOCKS proxy. is_socks()89 bool is_socks() const { 90 return scheme_ == SCHEME_SOCKS4 || scheme_ == SCHEME_SOCKS5; 91 } 92 93 // Returns true if this ProxyServer is a QUIC proxy. is_quic()94 bool is_quic() const { return scheme_ == SCHEME_QUIC; } 95 96 // Returns true if the ProxyServer's scheme is HTTP compatible (uses HTTP 97 // headers, has a CONNECT method for establishing tunnels). is_http_like()98 bool is_http_like() const { return is_http() || is_https() || is_quic(); } 99 100 // Returns true if the proxy server has HTTP semantics, AND 101 // the channel between the client and proxy server is secure. is_secure_http_like()102 bool is_secure_http_like() const { return is_https() || is_quic(); } 103 104 const HostPortPair& host_port_pair() const; 105 106 // Returns a ProxyServer representing DIRECT connections. Direct()107 static ProxyServer Direct() { 108 return ProxyServer(SCHEME_DIRECT, HostPortPair()); 109 } 110 111 // Returns the default port number for a proxy server with the specified 112 // scheme. Returns -1 if unknown. 113 static int GetDefaultPortForScheme(Scheme scheme); 114 115 bool operator==(const ProxyServer& other) const { 116 return scheme_ == other.scheme_ && 117 host_port_pair_.Equals(other.host_port_pair_); 118 } 119 120 bool operator!=(const ProxyServer& other) const { return !(*this == other); } 121 122 // Comparator function so this can be placed in a std::map. 123 bool operator<(const ProxyServer& other) const { 124 return std::tie(scheme_, host_port_pair_) < 125 std::tie(other.scheme_, other.host_port_pair_); 126 } 127 128 private: 129 Scheme scheme_ = SCHEME_INVALID; 130 HostPortPair host_port_pair_; 131 }; 132 133 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 134 const ProxyServer& proxy_server); 135 136 typedef std::pair<HostPortPair, ProxyServer> HostPortProxyPair; 137 138 } // namespace net 139 140 #endif // NET_BASE_PROXY_SERVER_H_ 141