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