xref: /aosp_15_r20/external/cronet/net/base/proxy_server.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2010 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 #include "net/base/proxy_server.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <optional>
10*6777b538SAndroid Build Coastguard Worker #include <ostream>
11*6777b538SAndroid Build Coastguard Worker #include <string>
12*6777b538SAndroid Build Coastguard Worker #include <string_view>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_string_util.h"
19*6777b538SAndroid Build Coastguard Worker #include "url/third_party/mozilla/url_parse.h"
20*6777b538SAndroid Build Coastguard Worker #include "url/url_canon.h"
21*6777b538SAndroid Build Coastguard Worker #include "url/url_canon_stdstring.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace net {
24*6777b538SAndroid Build Coastguard Worker 
ProxyServer(Scheme scheme,const HostPortPair & host_port_pair)25*6777b538SAndroid Build Coastguard Worker ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair)
26*6777b538SAndroid Build Coastguard Worker       : scheme_(scheme), host_port_pair_(host_port_pair) {
27*6777b538SAndroid Build Coastguard Worker   if (scheme_ == SCHEME_INVALID) {
28*6777b538SAndroid Build Coastguard Worker     // |host_port_pair| isn't relevant for these special schemes, so none should
29*6777b538SAndroid Build Coastguard Worker     // have been specified. It is important for this to be consistent since we
30*6777b538SAndroid Build Coastguard Worker     // do raw field comparisons in the equality and comparison functions.
31*6777b538SAndroid Build Coastguard Worker     DCHECK(host_port_pair.Equals(HostPortPair()));
32*6777b538SAndroid Build Coastguard Worker     host_port_pair_ = HostPortPair();
33*6777b538SAndroid Build Coastguard Worker   }
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker // static
FromSchemeHostAndPort(Scheme scheme,std::string_view host,std::string_view port_str)37*6777b538SAndroid Build Coastguard Worker ProxyServer ProxyServer::FromSchemeHostAndPort(Scheme scheme,
38*6777b538SAndroid Build Coastguard Worker                                                std::string_view host,
39*6777b538SAndroid Build Coastguard Worker                                                std::string_view port_str) {
40*6777b538SAndroid Build Coastguard Worker   // Create INVALID proxies directly using `ProxyServer()`.
41*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(scheme, SCHEME_INVALID);
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   int port_number =
44*6777b538SAndroid Build Coastguard Worker       url::ParsePort(port_str.data(), url::Component(0, port_str.size()));
45*6777b538SAndroid Build Coastguard Worker   if (port_number == url::PORT_UNSPECIFIED)
46*6777b538SAndroid Build Coastguard Worker     return FromSchemeHostAndPort(scheme, host, std::nullopt);
47*6777b538SAndroid Build Coastguard Worker   if (port_number == url::PORT_INVALID)
48*6777b538SAndroid Build Coastguard Worker     return ProxyServer();
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   DCHECK(base::IsValueInRangeForNumericType<uint16_t>(port_number));
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker   return FromSchemeHostAndPort(scheme, host,
53*6777b538SAndroid Build Coastguard Worker                                static_cast<uint16_t>(port_number));
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker // static
FromSchemeHostAndPort(Scheme scheme,std::string_view host,std::optional<uint16_t> port)57*6777b538SAndroid Build Coastguard Worker ProxyServer ProxyServer::FromSchemeHostAndPort(Scheme scheme,
58*6777b538SAndroid Build Coastguard Worker                                                std::string_view host,
59*6777b538SAndroid Build Coastguard Worker                                                std::optional<uint16_t> port) {
60*6777b538SAndroid Build Coastguard Worker   // Create INVALID proxies directly using `ProxyServer()`.
61*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(scheme, SCHEME_INVALID);
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   // Add brackets to IPv6 literals if missing, as required by url
64*6777b538SAndroid Build Coastguard Worker   // canonicalization.
65*6777b538SAndroid Build Coastguard Worker   std::string bracketed_host;
66*6777b538SAndroid Build Coastguard Worker   if (!host.empty() && host.front() != '[' &&
67*6777b538SAndroid Build Coastguard Worker       host.find(":") != std::string_view::npos) {
68*6777b538SAndroid Build Coastguard Worker     bracketed_host = base::StrCat({"[", host, "]"});
69*6777b538SAndroid Build Coastguard Worker     host = bracketed_host;
70*6777b538SAndroid Build Coastguard Worker   }
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker   std::string canonicalized_host;
73*6777b538SAndroid Build Coastguard Worker   url::StdStringCanonOutput canonicalized_output(&canonicalized_host);
74*6777b538SAndroid Build Coastguard Worker   url::Component component_output;
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   if (!url::CanonicalizeHost(host.data(), url::Component(0, host.size()),
77*6777b538SAndroid Build Coastguard Worker                              &canonicalized_output, &component_output)) {
78*6777b538SAndroid Build Coastguard Worker     return ProxyServer();
79*6777b538SAndroid Build Coastguard Worker   }
80*6777b538SAndroid Build Coastguard Worker   if (component_output.is_empty())
81*6777b538SAndroid Build Coastguard Worker     return ProxyServer();
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   canonicalized_output.Complete();
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   // Remove IPv6 literal bracketing, as required by HostPortPair.
86*6777b538SAndroid Build Coastguard Worker   std::string_view unbracketed_host = canonicalized_host;
87*6777b538SAndroid Build Coastguard Worker   if (canonicalized_host.front() == '[' && canonicalized_host.back() == ']')
88*6777b538SAndroid Build Coastguard Worker     unbracketed_host = unbracketed_host.substr(1, unbracketed_host.size() - 2);
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   // A uint16_t port is always valid and canonicalized.
91*6777b538SAndroid Build Coastguard Worker   uint16_t fixed_port = port.value_or(GetDefaultPortForScheme(scheme));
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   return ProxyServer(scheme, HostPortPair(unbracketed_host, fixed_port));
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker 
GetHost() const96*6777b538SAndroid Build Coastguard Worker std::string ProxyServer::GetHost() const {
97*6777b538SAndroid Build Coastguard Worker   return host_port_pair().HostForURL();
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker 
GetPort() const100*6777b538SAndroid Build Coastguard Worker uint16_t ProxyServer::GetPort() const {
101*6777b538SAndroid Build Coastguard Worker   return host_port_pair().port();
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker 
host_port_pair() const104*6777b538SAndroid Build Coastguard Worker const HostPortPair& ProxyServer::host_port_pair() const {
105*6777b538SAndroid Build Coastguard Worker   // Doesn't make sense to call this if the URI scheme doesn't
106*6777b538SAndroid Build Coastguard Worker   // have concept of a host.
107*6777b538SAndroid Build Coastguard Worker   DCHECK(is_valid());
108*6777b538SAndroid Build Coastguard Worker   return host_port_pair_;
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker // static
GetDefaultPortForScheme(Scheme scheme)112*6777b538SAndroid Build Coastguard Worker int ProxyServer::GetDefaultPortForScheme(Scheme scheme) {
113*6777b538SAndroid Build Coastguard Worker   switch (scheme) {
114*6777b538SAndroid Build Coastguard Worker     case SCHEME_HTTP:
115*6777b538SAndroid Build Coastguard Worker       return 80;
116*6777b538SAndroid Build Coastguard Worker     case SCHEME_SOCKS4:
117*6777b538SAndroid Build Coastguard Worker     case SCHEME_SOCKS5:
118*6777b538SAndroid Build Coastguard Worker       return 1080;
119*6777b538SAndroid Build Coastguard Worker     case SCHEME_HTTPS:
120*6777b538SAndroid Build Coastguard Worker     case SCHEME_QUIC:
121*6777b538SAndroid Build Coastguard Worker       return 443;
122*6777b538SAndroid Build Coastguard Worker     case SCHEME_INVALID:
123*6777b538SAndroid Build Coastguard Worker       break;
124*6777b538SAndroid Build Coastguard Worker   }
125*6777b538SAndroid Build Coastguard Worker   return -1;
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const ProxyServer & proxy_server)128*6777b538SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const ProxyServer& proxy_server) {
129*6777b538SAndroid Build Coastguard Worker   return os << ProxyServerToPacResultElement(proxy_server);
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker }  // namespace net
133